diff --git a/packages/core/src/api/lookup.ts b/packages/core/src/api/lookup.ts index ec5a1ddff..3cb71940b 100644 --- a/packages/core/src/api/lookup.ts +++ b/packages/core/src/api/lookup.ts @@ -43,8 +43,8 @@ import { findOrAdd } from "../utils/array.js"; type SearchResults = { sorted: (sortOptions?: SortOptions) => Promise>; - items: (sortOptions?: SortOptions) => Promise; - ids: (sortOptions?: SortOptions) => Promise; + items: (limit?: number, sortOptions?: SortOptions) => Promise; + ids: (limit?: number, sortOptions?: SortOptions) => Promise; }; type FuzzySearchField = { @@ -65,7 +65,7 @@ export default class Lookup { constructor(private readonly db: Database) {} notes(query: string, notes?: FilteredSelector): SearchResults { - return this.toSearchResults(async (sortOptions) => { + return this.toSearchResults(async (limit, sortOptions) => { const db = this.db.sql() as unknown as Kysely; const excludedIds = this.db.trash.cache.notes; @@ -400,7 +400,11 @@ export default class Lookup { trash(query: string): SearchResults { return { sorted: async (sortOptions?: SortOptions) => { - const { ids, items } = await this.filterTrash(query, sortOptions); + const { ids, items } = await this.filterTrash( + query, + undefined, + sortOptions + ); return new VirtualizedGrouping( ids.length, this.db.options.batchSize, @@ -413,8 +417,8 @@ export default class Lookup { } ); }, - items: async (sortOptions?: SortOptions) => { - const { items } = await this.filterTrash(query, sortOptions); + items: async (limit, sortOptions?: SortOptions) => { + const { items } = await this.filterTrash(query, limit, sortOptions); return items; }, ids: () => this.filterTrash(query).then(({ ids }) => ids) @@ -435,9 +439,10 @@ export default class Lookup { query: string, fields: FuzzySearchField[] ) { - return this.toSearchResults(async (sortOptions) => { + return this.toSearchResults(async (limit, sortOptions) => { const results = await this.filter(selector, query, fields, { - sortOptions + sortOptions, + limit }); return results.map((item) => item.id); }, selector); @@ -469,27 +474,33 @@ export default class Lookup { } private toSearchResults( - ids: (sortOptions?: SortOptions) => Promise, + ids: (limit?: number, sortOptions?: SortOptions) => Promise, selector: FilteredSelector ): SearchResults { return { - sorted: async (sortOptions?: SortOptions) => + sorted: async (sortOptions) => this.toVirtualizedGrouping( - await ids(sortOptions), + await ids(undefined, sortOptions), selector, sortOptions ), - items: async (sortOptions?: SortOptions) => - this.toItems(await ids(sortOptions), selector, sortOptions), + items: async (limit, sortOptions) => + this.toItems(await ids(limit, sortOptions), selector, sortOptions), ids }; } - private async filterTrash(query: string, sortOptions?: SortOptions) { + private async filterTrash( + query: string, + limit?: number, + sortOptions?: SortOptions + ) { const items = await this.db.trash.all(); const results: Map = new Map(); for (const item of items) { + if (limit !== undefined && results.size === limit) break; + const result = match(query, item.title); if (result.match) { results.set(item.id, { rank: result.score, item }); @@ -792,12 +803,6 @@ function stringToMatch(str: string): Match[] { ]; } -type Match = { - prefix: string; - match: string; - suffix: string; -}; - function mergeMatches(matches1: Match[], matches2: Match[]): Match[] | null { if (!matches1.length) return matches2; if (!matches2.length) return matches1; diff --git a/packages/core/src/database/backup.ts b/packages/core/src/database/backup.ts index 78fedd1e5..269cbd143 100644 --- a/packages/core/src/database/backup.ts +++ b/packages/core/src/database/backup.ts @@ -559,7 +559,8 @@ export default class Backup { !item || typeof item !== "object" || Array.isArray(item) || - isDeleted(item) + isDeleted(item) || + item.type === "searchResult" ) continue; // in v5.6 of the database, we did not set note history session's type