| 
									
										
										
										
											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-04-16 20:40:18 -04:00
										 |  |  | import server from "./server.js"; | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TreeCache { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |     load(noteRows, branchRows, parentToChildren) { | 
					
						
							|  |  |  |         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 = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.addResp(noteRows, branchRows, parentToChildren); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addResp(noteRows, branchRows, parentToChildren) { | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const relation of parentToChildren) { | 
					
						
							|  |  |  |             this.addBranchRelationship(relation.branchId, relation.childNoteId, relation.parentNoteId); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 14:49:20 -04:00
										 |  |  |     /** @return NoteShort */ | 
					
						
							|  |  |  |     async getNote(noteId) { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         if (this.notes[noteId] === undefined) { | 
					
						
							|  |  |  |             const resp = await server.post('tree/load', { | 
					
						
							|  |  |  |                 noteIds: [noteId] | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.addResp(resp.notes, resp.branches, resp.parentToChildren); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!this.notes[noteId]) { | 
					
						
							|  |  |  |             throw new Error(`Can't find note ${noteId}`); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |         return this.notes[noteId]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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) { | 
					
						
							|  |  |  |         this.addParentChildRelationship(parentNoteId, childNoteId); | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         this.childParentToBranch[childNoteId + '-' + parentNoteId] = branchId; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addParentChildRelationship(parentNoteId, childNoteId) { | 
					
						
							|  |  |  |         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-03-25 14:49:20 -04:00
										 |  |  |     /** @return Branch */ | 
					
						
							|  |  |  |     async getBranch(branchId) { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         if (this.branches[branchId] === undefined) { | 
					
						
							|  |  |  |             const resp = await server.post('tree/load', { | 
					
						
							|  |  |  |                 branchIds: [branchId] | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.addResp(resp.notes, resp.branches, resp.parentToChildren); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!this.branches[branchId]) { | 
					
						
							|  |  |  |             throw new Error(`Can't find branch ${branchId}`); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |         return this.branches[branchId]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 14:49:20 -04:00
										 |  |  |     /** @return Branch */ | 
					
						
							|  |  |  |     async getBranchByChildParent(childNoteId, parentNoteId) { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:40:18 -04:00
										 |  |  |         // this will make sure the note and its relationships are loaded
 | 
					
						
							|  |  |  |         await this.getNote(parentNoteId); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 12:29:00 -04:00
										 |  |  |         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 20:40:18 -04:00
										 |  |  |         return await this.getBranch(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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         treeCache.childParentToBranch[childNoteId + '-' + newParentNoteId] = treeCache.childParentToBranch[childNoteId + '-' + oldParentNoteId]; | 
					
						
							|  |  |  |         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; |