« get me outta code hell

client: stub interesting search internals - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/static
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-05-05 14:45:02 -0300
committer(quasar) nebula <qznebula@protonmail.com>2024-05-31 12:11:50 -0300
commitda951b7f18b8a67c60de96b1b506a1b1a825bbbd (patch)
tree4b0528d0b2d7d830e15dc20eb6bde49cc70306a8 /src/static
parentb76fdc3b5ef0ce800c78014bfb879a5acc0329a9 (diff)
client: stub interesting search internals
Diffstat (limited to 'src/static')
-rw-r--r--src/static/js/client.js26
-rw-r--r--src/static/js/search-worker.js88
2 files changed, 97 insertions, 17 deletions
diff --git a/src/static/js/client.js b/src/static/js/client.js
index 560a0d36..d8828ad2 100644
--- a/src/static/js/client.js
+++ b/src/static/js/client.js
@@ -3696,16 +3696,15 @@ function showSidebarSearchResults(results) {
 
   const flatResults =
     Object.entries(results)
+      .filter(([index]) => index === 'generic')
       .flatMap(([index, results]) => results
-        .flatMap(({field, result}) => result
-          .flatMap(({doc, id}) => ({
-            index,
-            field,
-            reference: id ?? null,
-            referenceType: (id ? id.split(':')[0] : null),
-            directory: (id ? id.split(':')[1] : null),
-            data: doc,
-          }))));
+        .flatMap(({doc, id}) => ({
+          index,
+          reference: id ?? null,
+          referenceType: (id ? id.split(':')[0] : null),
+          directory: (id ? id.split(':')[1] : null),
+          data: doc,
+        })));
 
   while (info.results.firstChild) {
     info.results.firstChild.remove();
@@ -3714,8 +3713,6 @@ function showSidebarSearchResults(results) {
   cssProp(info.resultsContainer, 'display', 'block');
 
   for (const result of flatResults) {
-    if (result.index !== 'generic') continue;
-
     const el = generateSidebarSearchResult(result);
     if (!el) continue;
 
@@ -3743,6 +3740,13 @@ function generateSidebarSearchResult(result) {
       break;
     }
 
+    case 'artist': {
+      preparedSlots.href =
+        openArtist(result.directory);
+
+      break;
+    }
+
     default:
       return null;
   }
diff --git a/src/static/js/search-worker.js b/src/static/js/search-worker.js
index 0b3c8cc5..028b27c3 100644
--- a/src/static/js/search-worker.js
+++ b/src/static/js/search-worker.js
@@ -1,5 +1,5 @@
 import {makeSearchIndex, searchSpec} from '../shared-util/search-spec.js';
-import {withEntries} from '../shared-util/sugar.js';
+import {empty, unique, withEntries} from '../shared-util/sugar.js';
 
 import FlexSearch from '../lib/flexsearch/flexsearch.bundle.module.min.js';
 
@@ -68,7 +68,7 @@ async function handleWindowActionMessage(message) {
 
   switch (message.data.action) {
     case 'search':
-      value = await performSearch(message.data.options);
+      value = await performSearchAction(message.data.options);
       break;
 
     default:
@@ -96,11 +96,87 @@ function postActionResult(id, status, value) {
   });
 }
 
-function performSearch({query, options}) {
-  return (
-    withEntries(indexes, entries => entries
+function performSearchAction({query, options}) {
+  const {generic, ...otherIndexes} = indexes;
+
+  const genericResults =
+    queryGenericIndex(generic, query, options);
+
+  const otherResults =
+    withEntries(otherIndexes, entries => entries
       .map(([indexName, index]) => [
         indexName,
         index.search(query, options),
-      ])));
+      ]));
+
+  return {
+    generic: genericResults,
+    ...otherResults,
+  };
+}
+
+function queryGenericIndex(index, query, options) {
+  const terms = query.split(' ');
+  const particles = particulate(terms);
+  console.log(particles);
+
+  const boilerplate = queryBoilerplate(index, query, options);
+
+  const {primaryName} = boilerplate.fieldResults;
+
+  return boilerplate.constitute(primaryName);
+}
+
+function particulate(terms) {
+  if (empty(terms)) return [];
+
+  const results = [];
+
+  for (let slice = 1; slice <= 2; slice++) {
+    if (slice === terms.length) {
+      break;
+    }
+
+    const front = terms.slice(0, slice);
+    const back = terms.slice(slice);
+
+    results.push(...
+      particulate(back)
+        .map(result => [
+          {terms: front},
+          ...result
+        ]));
+  }
+
+  results.push([{terms}]);
+
+  return results;
+}
+
+function queryBoilerplate(index, query, options) {
+  const rawResults =
+    index.search(query, options);
+
+  const fieldResults =
+    Object.fromEntries(
+      rawResults
+        .map(({field, result}) => [
+          field,
+          result.map(({id}) => id),
+        ]));
+
+  const idToDoc =
+    Object.fromEntries(
+      rawResults
+        .flatMap(({result}) => result)
+        .map(({id, doc}) => [id, doc]));
+
+  return {
+    rawResults,
+    fieldResults,
+    idToDoc,
+
+    constitute: ids =>
+      ids.map(id => ({id, doc: idToDoc[id]})),
+  };
 }