diff --git a/src/lib/db/store.spec.ts b/src/lib/db/store.spec.ts index 8fc09d020c..55ddaa5ff6 100644 --- a/src/lib/db/store.spec.ts +++ b/src/lib/db/store.spec.ts @@ -307,4 +307,81 @@ describe('DbStore', () => { ).toEqual(2) }) }) + + describe('#purgeNote', () => { + it('removes note from note map', async () => { + // Given + const { result } = prepareDbStore() + let storage: NoteStorage + let noteDoc: NoteDoc | undefined + await act(async () => { + await result.current.initialize() + storage = await result.current.createStorage('test') + await result.current.createFolder(storage.id, '/test') + noteDoc = await result.current.createNote(storage.id, { + title: 'testNote' + }) + + // When + await result.current.purgeNote(storage.id, noteDoc!._id) + + // Then + expect( + result.current.storageMap[storage!.id]!.noteMap[noteDoc!._id] + ).toBeUndefined() + }) + }) + + it('removes note from folder map', async () => { + // Given + const { result } = prepareDbStore() + let storage: NoteStorage + let noteDoc: NoteDoc | undefined + await act(async () => { + await result.current.initialize() + storage = await result.current.createStorage('test') + await result.current.createFolder(storage.id, '/test') + noteDoc = await result.current.createNote(storage.id, { + title: 'testNote', + folderPathname: '/test' + }) + + // When + await result.current.purgeNote(storage.id, noteDoc!._id) + + // Then + expect( + result.current.storageMap[storage!.id]!.folderMap[ + noteDoc!.folderPathname + ]!.noteIdSet.has(noteDoc!._id) + ).toEqual(false) + }) + }) + + it('removes note tags from tag map', async () => { + // Given + const { result } = prepareDbStore() + let storage: NoteStorage + let noteDoc: NoteDoc | undefined + await act(async () => { + await result.current.initialize() + storage = await result.current.createStorage('test') + await result.current.createFolder(storage.id, '/test') + noteDoc = await result.current.createNote(storage.id, { + title: 'testNote', + tags: ['testTag'] + }) + + // When + await result.current.purgeNote(storage.id, noteDoc!._id) + + // Then + expect( + result.current.storageMap[storage!.id]!.tagMap[ + 'testTag' + ]!!.noteIdSet.has(noteDoc!._id) + ).toEqual(false) + }) + }) + }) }) diff --git a/src/lib/db/store.ts b/src/lib/db/store.ts index 2a1a1fa0d5..1da437d61b 100644 --- a/src/lib/db/store.ts +++ b/src/lib/db/store.ts @@ -46,6 +46,7 @@ export interface DbStore { noteProps: Partial ): Promise trashNote(storageId: string, noteId: string): Promise + purgeNote(storageId: string, noteId: string): Promise } export function createDbStoreCreator( @@ -398,6 +399,58 @@ export function createDbStoreCreator( [storageMap] ) + const purgeNote = useCallback( + async (storageId: string, noteId: string) => { + const storage = storageMap[storageId] + if (storage == null) { + return + } + + await storage.db.purgeNote(noteId) + + const noteDoc = storageMap[storageId]!.noteMap[noteId]! + + const noteMap = { ...storageMap[storageId]!.noteMap } + delete noteMap[noteId] + + const newFolderNoteIdSet = new Set( + storage.folderMap[noteDoc.folderPathname]!.noteIdSet + ) + newFolderNoteIdSet.delete(noteDoc._id) + const folder: PopulatedFolderDoc = { + ...storage.folderMap[noteDoc.folderPathname]!, + noteIdSet: newFolderNoteIdSet + } + + const modifiedTags: ObjectMap = noteDoc.tags.reduce( + (acc, tag) => { + const newNoteIdSet = new Set(storage.tagMap[tag]!.noteIdSet) + newNoteIdSet.delete(noteDoc._id) + acc[tag] = { + ...storage.tagMap[tag]!, + noteIdSet: newNoteIdSet + } + return acc + }, + {} + ) + + setStorageMap( + produce((draft: ObjectMap) => { + draft[storageId]!.noteMap = noteMap + draft[storageId]!.folderMap[noteDoc.folderPathname] = folder + draft[storageId]!.tagMap = { + ...storage.tagMap, + ...modifiedTags + } + }) + ) + + return + }, + [storageMap] + ) + return { initialized, storageMap, @@ -409,7 +462,8 @@ export function createDbStoreCreator( removeFolder, createNote, updateNote, - trashNote + trashNote, + purgeNote } } }