| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | import utils from "./utils.js"; | 
					
						
							| 
									
										
										
										
											2018-03-25 13:02:39 -04:00
										 |  |  | import Branch from "../entities/branch.js"; | 
					
						
							|  |  |  | import NoteShort from "../entities/note_short.js"; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:29:35 -04:00
										 |  |  | import infoService from "./info.js"; | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  | import messagingService from "./messaging.js"; | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | import server from "./server.js"; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TreeCache { | 
					
						
							| 
									
										
										
										
											2018-08-16 23:00:04 +02:00
										 |  |  |     constructor() { | 
					
						
							|  |  |  |         this.init(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |     load(noteRows, branchRows, relations) { | 
					
						
							| 
									
										
										
										
											2018-08-16 23:00:04 +02:00
										 |  |  |         this.init(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.addResp(noteRows, branchRows, relations); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     init() { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         this.parents = {}; | 
					
						
							|  |  |  |         this.children = {}; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |         this.childParentToBranch = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @type {Object.<string, NoteShort>} */ | 
					
						
							|  |  |  |         this.notes = {}; | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /** @type {Object.<string, Branch>} */ | 
					
						
							|  |  |  |         this.branches = {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |     addResp(noteRows, branchRows, relations) { | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |         for (const noteRow of noteRows) { | 
					
						
							|  |  |  |             const note = new NoteShort(this, noteRow); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.notes[note.noteId] = note; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const branchRow of branchRows) { | 
					
						
							|  |  |  |             const branch = new Branch(this, branchRow); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.addBranch(branch); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         for (const relation of relations) { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |             this.addBranchRelationship(relation.branchId, relation.childNoteId, relation.parentNoteId); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-16 23:00:04 +02:00
										 |  |  |     async getNotes(noteIds, silentNotFoundError = false) { | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         const missingNoteIds = noteIds.filter(noteId => this.notes[noteId] === undefined); | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         if (missingNoteIds.length > 0) { | 
					
						
							|  |  |  |             const resp = await server.post('tree/load', { noteIds: missingNoteIds }); | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |             this.addResp(resp.notes, resp.branches, resp.relations); | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         return noteIds.map(noteId => { | 
					
						
							| 
									
										
										
										
											2018-08-16 23:00:04 +02:00
										 |  |  |             if (!this.notes[noteId] && !silentNotFoundError) { | 
					
						
							| 
									
										
										
										
											2018-11-12 23:34:22 +01:00
										 |  |  |                 messagingService.logError(`Can't find note "${noteId}"`); | 
					
						
							| 
									
										
										
										
											2018-08-06 11:30:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-12 12:59:38 +02:00
										 |  |  |                 return null; | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 return this.notes[noteId]; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-08-12 12:59:38 +02:00
										 |  |  |         }).filter(note => note !== null); | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @return NoteShort */ | 
					
						
							|  |  |  |     async getNote(noteId) { | 
					
						
							| 
									
										
										
										
											2018-05-26 16:16:34 -04:00
										 |  |  |         if (noteId === 'none') { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         return (await this.getNotes([noteId]))[0]; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addBranch(branch) { | 
					
						
							|  |  |  |         this.branches[branch.branchId] = branch; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         this.addBranchRelationship(branch.branchId, branch.noteId, branch.parentNoteId); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |     addBranchRelationship(branchId, childNoteId, parentNoteId) { | 
					
						
							| 
									
										
										
										
											2018-05-26 16:16:34 -04:00
										 |  |  |         if (parentNoteId === 'none') { // applies only to root element
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         this.childParentToBranch[childNoteId + '-' + parentNoteId] = branchId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.parents[childNoteId] = this.parents[childNoteId] || []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!this.parents[childNoteId].includes(parentNoteId)) { | 
					
						
							|  |  |  |             this.parents[childNoteId].push(parentNoteId); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.children[parentNoteId] = this.children[parentNoteId] || []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!this.children[parentNoteId].includes(childNoteId)) { | 
					
						
							|  |  |  |             this.children[parentNoteId].push(childNoteId); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     add(note, branch) { | 
					
						
							|  |  |  |         this.notes[note.noteId] = note; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.addBranch(branch); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |     async getBranches(branchIds) { | 
					
						
							|  |  |  |         const missingBranchIds = branchIds.filter(branchId => this.branches[branchId] === undefined); | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         if (missingBranchIds.length > 0) { | 
					
						
							|  |  |  |             const resp = await server.post('tree/load', { branchIds: branchIds }); | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |             this.addResp(resp.notes, resp.branches, resp.relations); | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         return branchIds.map(branchId => { | 
					
						
							|  |  |  |             if (!this.branches[branchId]) { | 
					
						
							|  |  |  |                 throw new Error(`Can't find branch ${branchId}`); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 return this.branches[branchId]; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** @return Branch */ | 
					
						
							|  |  |  |     async getBranch(branchId) { | 
					
						
							|  |  |  |         return (await this.getBranches([branchId]))[0]; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 14:49:20 -04:00
										 |  |  |     /** @return Branch */ | 
					
						
							|  |  |  |     async getBranchByChildParent(childNoteId, parentNoteId) { | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         const branchId = this.getBranchIdByChildParent(childNoteId, parentNoteId); | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         return await this.getBranch(branchId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getBranchIdByChildParent(childNoteId, parentNoteId) { | 
					
						
							|  |  |  |         const key = childNoteId + '-' + parentNoteId; | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         const branchId = this.childParentToBranch[key]; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         if (!branchId) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:29:35 -04:00
										 |  |  |             infoService.throwError("Cannot find branch for child-parent=" + key); | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 23:13:33 -04:00
										 |  |  |         return branchId; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-26 22:11:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Move note from one parent to another. */ | 
					
						
							|  |  |  |     async moveNote(childNoteId, oldParentNoteId, newParentNoteId) { | 
					
						
							|  |  |  |         utils.assertArguments(childNoteId, oldParentNoteId, newParentNoteId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (oldParentNoteId === newParentNoteId) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-05 19:25:22 +01:00
										 |  |  |         const branchId = treeCache.childParentToBranch[childNoteId + '-' + oldParentNoteId]; | 
					
						
							|  |  |  |         const branch = await this.getBranch(branchId); | 
					
						
							|  |  |  |         branch.parentNoteId = newParentNoteId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         treeCache.childParentToBranch[childNoteId + '-' + newParentNoteId] = branchId; | 
					
						
							| 
									
										
										
										
											2018-03-26 22:11:45 -04:00
										 |  |  |         delete treeCache.childParentToBranch[childNoteId + '-' + oldParentNoteId]; // this is correct because we know that oldParentId isn't same as newParentId
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // remove old associations
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         treeCache.parents[childNoteId] = treeCache.parents[childNoteId].filter(p => p !== oldParentNoteId); | 
					
						
							|  |  |  |         treeCache.children[oldParentNoteId] = treeCache.children[oldParentNoteId].filter(ch => ch !== childNoteId); | 
					
						
							| 
									
										
										
										
											2018-03-26 22:11:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // add new associations
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         treeCache.parents[childNoteId].push(newParentNoteId); | 
					
						
							| 
									
										
										
										
											2018-03-26 22:11:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         treeCache.children[newParentNoteId] = treeCache.children[newParentNoteId] || []; // this might be first child
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         treeCache.children[newParentNoteId].push(childNoteId); | 
					
						
							| 
									
										
										
										
											2018-03-26 22:11:45 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const treeCache = new TreeCache(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default treeCache; |