mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	note cache breakup into classes, WIP
This commit is contained in:
		
							
								
								
									
										236
									
								
								src/services/note_cache/entities/note.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								src/services/note_cache/entities/note.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,236 @@ | ||||
| export default class Note { | ||||
|     constructor(row) { | ||||
|         /** @param {string} */ | ||||
|         this.noteId = row.noteId; | ||||
|         /** @param {string} */ | ||||
|         this.title = row.title; | ||||
|         /** @param {boolean} */ | ||||
|         this.isProtected = !!row.isProtected; | ||||
|         /** @param {boolean} */ | ||||
|         this.isDecrypted = !row.isProtected || !!row.isContentAvailable; | ||||
|         /** @param {Branch[]} */ | ||||
|         this.parentBranches = []; | ||||
|         /** @param {Note[]} */ | ||||
|         this.parents = []; | ||||
|         /** @param {Note[]} */ | ||||
|         this.children = []; | ||||
|         /** @param {Attribute[]} */ | ||||
|         this.ownedAttributes = []; | ||||
|  | ||||
|         /** @param {Attribute[]|null} */ | ||||
|         this.attributeCache = null; | ||||
|         /** @param {Attribute[]|null} */ | ||||
|         this.inheritableAttributeCache = null; | ||||
|  | ||||
|         /** @param {Attribute[]} */ | ||||
|         this.targetRelations = []; | ||||
|  | ||||
|         /** @param {string|null} */ | ||||
|         this.flatTextCache = null; | ||||
|  | ||||
|         if (protectedSessionService.isProtectedSessionAvailable()) { | ||||
|             decryptProtectedNote(this); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** @return {Attribute[]} */ | ||||
|     get attributes() { | ||||
|         if (!this.attributeCache) { | ||||
|             const parentAttributes = this.ownedAttributes.slice(); | ||||
|  | ||||
|             if (this.noteId !== 'root') { | ||||
|                 for (const parentNote of this.parents) { | ||||
|                     parentAttributes.push(...parentNote.inheritableAttributes); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             const templateAttributes = []; | ||||
|  | ||||
|             for (const ownedAttr of parentAttributes) { // parentAttributes so we process also inherited templates | ||||
|                 if (ownedAttr.type === 'relation' && ownedAttr.name === 'template') { | ||||
|                     const templateNote = notes[ownedAttr.value]; | ||||
|  | ||||
|                     if (templateNote) { | ||||
|                         templateAttributes.push(...templateNote.attributes); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             this.attributeCache = parentAttributes.concat(templateAttributes); | ||||
|             this.inheritableAttributeCache = []; | ||||
|  | ||||
|             for (const attr of this.attributeCache) { | ||||
|                 if (attr.isInheritable) { | ||||
|                     this.inheritableAttributeCache.push(attr); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return this.attributeCache; | ||||
|     } | ||||
|  | ||||
|     /** @return {Attribute[]} */ | ||||
|     get inheritableAttributes() { | ||||
|         if (!this.inheritableAttributeCache) { | ||||
|             this.attributes; // will refresh also this.inheritableAttributeCache | ||||
|         } | ||||
|  | ||||
|         return this.inheritableAttributeCache; | ||||
|     } | ||||
|  | ||||
|     hasAttribute(type, name) { | ||||
|         return this.attributes.find(attr => attr.type === type && attr.name === name); | ||||
|     } | ||||
|  | ||||
|     get isArchived() { | ||||
|         return this.hasAttribute('label', 'archived'); | ||||
|     } | ||||
|  | ||||
|     get isHideInAutocompleteOrArchived() { | ||||
|         return this.attributes.find(attr => | ||||
|             attr.type === 'label' | ||||
|             && ["archived", "hideInAutocomplete"].includes(attr.name)); | ||||
|     } | ||||
|  | ||||
|     get hasInheritableOwnedArchivedLabel() { | ||||
|         return !!this.ownedAttributes.find(attr => attr.type === 'label' && attr.name === 'archived' && attr.isInheritable); | ||||
|     } | ||||
|  | ||||
|     // will sort the parents so that non-archived are first and archived at the end | ||||
|     // this is done so that non-archived paths are always explored as first when searching for note path | ||||
|     resortParents() { | ||||
|         this.parents.sort((a, b) => a.hasInheritableOwnedArchivedLabel ? 1 : -1); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return {string} - returns flattened textual representation of note, prefixes and attributes usable for searching | ||||
|      */ | ||||
|     get flatText() { | ||||
|         if (!this.flatTextCache) { | ||||
|             if (this.isHideInAutocompleteOrArchived) { | ||||
|                 this.flatTextCache = " "; // can't be empty | ||||
|                 return this.flatTextCache; | ||||
|             } | ||||
|  | ||||
|             this.flatTextCache = ''; | ||||
|  | ||||
|             for (const branch of this.parentBranches) { | ||||
|                 if (branch.prefix) { | ||||
|                     this.flatTextCache += branch.prefix + ' - '; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             this.flatTextCache += this.title; | ||||
|  | ||||
|             for (const attr of this.attributes) { | ||||
|                 // it's best to use space as separator since spaces are filtered from the search string by the tokenization into words | ||||
|                 this.flatTextCache += (attr.type === 'label' ? '#' : '@') + attr.name; | ||||
|  | ||||
|                 if (attr.value) { | ||||
|                     this.flatTextCache += '=' + attr.value; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             this.flatTextCache = this.flatTextCache.toLowerCase(); | ||||
|         } | ||||
|  | ||||
|         return this.flatTextCache; | ||||
|     } | ||||
|  | ||||
|     invalidateThisCache() { | ||||
|         this.flatTextCache = null; | ||||
|  | ||||
|         this.attributeCache = null; | ||||
|         this.inheritableAttributeCache = null; | ||||
|     } | ||||
|  | ||||
|     invalidateSubtreeCaches() { | ||||
|         this.invalidateThisCache(); | ||||
|  | ||||
|         for (const childNote of this.children) { | ||||
|             childNote.invalidateSubtreeCaches(); | ||||
|         } | ||||
|  | ||||
|         for (const targetRelation of this.targetRelations) { | ||||
|             if (targetRelation.name === 'template') { | ||||
|                 const note = targetRelation.note; | ||||
|  | ||||
|                 if (note) { | ||||
|                     note.invalidateSubtreeCaches(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     invalidateSubtreeFlatText() { | ||||
|         this.flatTextCache = null; | ||||
|  | ||||
|         for (const childNote of this.children) { | ||||
|             childNote.invalidateSubtreeFlatText(); | ||||
|         } | ||||
|  | ||||
|         for (const targetRelation of this.targetRelations) { | ||||
|             if (targetRelation.name === 'template') { | ||||
|                 const note = targetRelation.note; | ||||
|  | ||||
|                 if (note) { | ||||
|                     note.invalidateSubtreeFlatText(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     get isTemplate() { | ||||
|         return !!this.targetRelations.find(rel => rel.name === 'template'); | ||||
|     } | ||||
|  | ||||
|     /** @return {Note[]} */ | ||||
|     get subtreeNotesIncludingTemplated() { | ||||
|         const arr = [[this]]; | ||||
|  | ||||
|         for (const childNote of this.children) { | ||||
|             arr.push(childNote.subtreeNotesIncludingTemplated); | ||||
|         } | ||||
|  | ||||
|         for (const targetRelation of this.targetRelations) { | ||||
|             if (targetRelation.name === 'template') { | ||||
|                 const note = targetRelation.note; | ||||
|  | ||||
|                 if (note) { | ||||
|                     arr.push(note.subtreeNotesIncludingTemplated); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return arr.flat(); | ||||
|     } | ||||
|  | ||||
|     /** @return {Note[]} */ | ||||
|     get subtreeNotes() { | ||||
|         const arr = [[this]]; | ||||
|  | ||||
|         for (const childNote of this.children) { | ||||
|             arr.push(childNote.subtreeNotes); | ||||
|         } | ||||
|  | ||||
|         return arr.flat(); | ||||
|     } | ||||
|  | ||||
|     /** @return {Note[]} - returns only notes which are templated, does not include their subtrees | ||||
|      *                     in effect returns notes which are influenced by note's non-inheritable attributes */ | ||||
|     get templatedNotes() { | ||||
|         const arr = [this]; | ||||
|  | ||||
|         for (const targetRelation of this.targetRelations) { | ||||
|             if (targetRelation.name === 'template') { | ||||
|                 const note = targetRelation.note; | ||||
|  | ||||
|                 if (note) { | ||||
|                     arr.push(note); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return arr; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user