perf(frontend): Notes Manager
This commit is contained in:
		
							parent
							
								
									ae949af6c3
								
							
						
					
					
						commit
						e288d56181
					
				|  | @ -0,0 +1,94 @@ | |||
| import { Note, UserLite } from "misskey-js/built/entities"; | ||||
| import { Ref, ref, ComputedRef, computed } from "vue"; | ||||
| import { api } from "./api"; | ||||
| 
 | ||||
| export class EntitiyManager<T extends { id: string }> { | ||||
|     private entities: Map<T['id'], Ref<T>>; | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.entities = new Map(); | ||||
|     } | ||||
| 
 | ||||
|     public set(item: T): Ref<T> { | ||||
|         const cached = this.entities.get(item.id); | ||||
|         if (cached) { | ||||
|             cached.value = item; | ||||
|         } else { | ||||
|             this.entities.set(item.id, ref(item) as Ref<T>); | ||||
|         } | ||||
|         return this.get(item.id)!; | ||||
|     } | ||||
| 
 | ||||
|     public get(id: string): Ref<T> | undefined { | ||||
|         return this.entities.get(id); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export const userLiteManager = new EntitiyManager<UserLite>(); | ||||
| 
 | ||||
| type OmittedNote = Omit<Note, 'user' | 'renote' | 'reply'>; | ||||
| type InternalCachedNote = Ref<OmittedNote>; | ||||
| 
 | ||||
| export class NoteManager { | ||||
|     private notes: Map<Note['id'], InternalCachedNote>; | ||||
|     private updatedAt: Map<Note['id'], number>; | ||||
|     private captureing: Map<Note['id'], number>; | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.notes = new Map(); | ||||
|         this.updatedAt = new Map(); | ||||
|         this.captureing = new Map(); | ||||
|     } | ||||
| 
 | ||||
|     public set(_note: Note): ComputedRef<Note> { | ||||
|         const note: Note = { ..._note }; | ||||
|         userLiteManager.set(note.user); | ||||
|         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 | ||||
|         //@ts-ignore
 | ||||
|         delete note.user; | ||||
|         if (note.renote) this.set(note.renote); | ||||
|         delete note.renote; | ||||
|         if (note.reply) this.set(note.reply); | ||||
|         delete note.reply; | ||||
|         const cached = this.notes.get(note.id); | ||||
|         if (cached) { | ||||
|             cached.value = note; | ||||
|         } else { | ||||
|             this.notes.set(note.id, ref(note)); | ||||
|         } | ||||
|         this.updatedAt.set(note.id, Date.now()); | ||||
|         return this.get(note.id)!; | ||||
|     } | ||||
| 
 | ||||
|     public get(id: string): ComputedRef<Note> | undefined { | ||||
|         const note: InternalCachedNote | undefined = this.notes.get(id); | ||||
|         if (!note) return undefined; | ||||
| 
 | ||||
|         return computed<Note>(() => { | ||||
|             const user = userLiteManager.get(note.value.userId)!; | ||||
|             const renote = note.value.renoteId ? this.get(note.value.renoteId) : undefined; | ||||
|             const reply = note.value.replyId ? this.get(note.value.replyId) : undefined; | ||||
| 
 | ||||
|             return { | ||||
|                 ...note.value, | ||||
|                 user: user.value, | ||||
|                 renote: renote?.value, | ||||
|                 reply: reply?.value, | ||||
|             }; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     public async fetch(id: string, force = false): Promise<ComputedRef<Note>> { | ||||
|         if (!force) { | ||||
|             const updatedAt = this.updatedAt.get(id); | ||||
|             if (updatedAt && Date.now() - updatedAt < 1000 * 30) { | ||||
|                 const cachedNote = this.get(id); | ||||
|                 if (cachedNote) { | ||||
|                     return cachedNote as ComputedRef<Note>; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         const fetchedNote = await api('notes/show', { noteId: id }); | ||||
|         return this.set(fetchedNote); | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue