From 39fc3d74b1e7e193442ab77962935fb50a593c5d Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 3 May 2024 16:26:43 -0300 Subject: search: refactor search spec definition & interfaces --- src/util/search-spec.js | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/util/search-spec.js (limited to 'src/util/search-spec.js') diff --git a/src/util/search-spec.js b/src/util/search-spec.js new file mode 100644 index 00000000..b26869a2 --- /dev/null +++ b/src/util/search-spec.js @@ -0,0 +1,150 @@ +// Index structures shared by client and server, and relevant interfaces. + +export const searchSpec = { + albums: { + query: ({albumData}) => albumData, + + process: (album) => ({ + name: + album.name, + + groups: + album.groups.map(group => group.name), + }), + + index: [ + 'name', + 'groups', + ], + }, + + tracks: { + query: ({trackData}) => trackData, + + process: (track) => ({ + name: + track.name, + + color: + track.color, + + album: + track.album.name, + + albumDirectory: + track.album.directory, + + artists: + track.artistContribs + .map(contrib => contrib.artist) + .flatMap(artist => [artist.name, ...artist.aliasNames]), + + additionalNames: + track.additionalNames + .map(entry => entry.name), + + artworkKind: + (track.hasUniqueCoverArt + ? 'track' + : track.album.hasCoverArt + ? 'album' + : 'none'), + }), + + index: [ + 'name', + 'album', + 'artists', + 'additionalNames', + ], + + store: [ + 'color', + 'name', + 'albumDirectory', + 'artworkKind', + ], + }, + + artists: { + query: ({artistData}) => + artistData + .filter(artist => !artist.isAlias), + + process: (artist) => ({ + names: + [artist.name, ...artist.aliasNames], + }), + + index: [ + 'names', + ], + }, + + groups: { + query: ({groupData}) => groupData, + + process: (group) => ({ + names: group.name, + description: group.description, + // category: group.category + }), + + index: [ + 'name', + 'description', + // 'category', + ], + }, + + flashes: { + query: ({flashData}) => flashData, + + process: (flash) => ({ + name: + flash.name, + + tracks: + flash.featuredTracks + .map(track => track.name), + + contributors: + flash.contributorContribs + .map(contrib => contrib.artist) + .flatMap(artist => [artist.name, ...artist.aliasNames]), + }), + + index: [ + 'name', + 'tracks', + 'contributors', + ], + }, +}; + +export function makeSearchIndex(descriptor, {FlexSearch}) { + return new FlexSearch.Document({ + id: 'reference', + index: descriptor.index, + store: descriptor.store, + }); +} + +export function populateSearchIndex(index, descriptor, {wikiData}) { + const collection = descriptor.query(wikiData); + + for (const thing of collection) { + const reference = thing.constructor.getReference(thing); + + let processed; + try { + processed = descriptor.process(thing); + } catch (caughtError) { + throw new Error( + `Failed to process searchable thing ${reference}`, + {cause: caughtError}); + } + + index.add({reference, ...processed}); + } +} -- cgit 1.3.0-6-gf8a5