« get me outta code hell

search: refactor search spec definition & interfaces - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/util/search-spec.js
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-05-03 16:26:43 -0300
committer(quasar) nebula <qznebula@protonmail.com>2024-05-31 12:11:49 -0300
commit39fc3d74b1e7e193442ab77962935fb50a593c5d (patch)
tree963dbeffaa29b0c8b2ebcb7999768dbdbe81d29f /src/util/search-spec.js
parentd5ec0affefaaa3c1d73a6abcfa6a3aa6abc703e4 (diff)
search: refactor search spec definition & interfaces
Diffstat (limited to 'src/util/search-spec.js')
-rw-r--r--src/util/search-spec.js150
1 files changed, 150 insertions, 0 deletions
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});
+  }
+}