« 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
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
parentd5ec0affefaaa3c1d73a6abcfa6a3aa6abc703e4 (diff)
search: refactor search spec definition & interfaces
Diffstat (limited to 'src/util')
-rw-r--r--src/util/search-spec.js150
-rw-r--r--src/util/searchSchema.js46
2 files changed, 150 insertions, 46 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});
+  }
+}
diff --git a/src/util/searchSchema.js b/src/util/searchSchema.js
deleted file mode 100644
index dffd1c1f..00000000
--- a/src/util/searchSchema.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Index structures shared by client and server.
-
-export function makeSearchIndexes(FlexSearch, documentOptions = {}) {
-  const doc = documentSchema =>
-    new FlexSearch.Document({
-      id: 'reference',
-      ...documentOptions,
-      ...documentSchema,
-    });
-
-  const indexes = {
-    albums: doc({
-      index: ['name', 'groups'],
-    }),
-
-    tracks: doc({
-      index: [
-        'name',
-        'album',
-        'artists',
-        'additionalNames',
-      ],
-
-      store: [
-        'color',
-        'name',
-        'albumDirectory',
-        'artworkKind',
-      ],
-    }),
-
-    artists: doc({
-      index: ['names'],
-    }),
-
-    groups: doc({
-      index: ['name', 'description', 'category'],
-    }),
-
-    flashes: doc({
-      index: ['name', 'tracks', 'contributors'],
-    }),
-  };
-
-  return indexes;
-}