« 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/js/search-worker.js
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/js/search-worker.js
parentb76fdc3b5ef0ce800c78014bfb879a5acc0329a9 (diff)
client: stub interesting search internals
Diffstat (limited to 'src/static/js/search-worker.js')
-rw-r--r--src/static/js/search-worker.js88
1 files changed, 82 insertions, 6 deletions
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]})),
+  };
 }