diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2024-05-02 15:15:55 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2024-05-31 12:11:48 -0300 |
commit | f415551fb45174f2618f916fd323fb076adfd7a6 (patch) | |
tree | 6a8752ba4a647f635c80dd069357eb944404fd2e /src/static/js/search-worker.js | |
parent | 284f32fc0aa6d6aa513961d53dfc091cd09580c2 (diff) |
client: move search into worker, defer loading
Diffstat (limited to 'src/static/js/search-worker.js')
-rw-r--r-- | src/static/js/search-worker.js | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/static/js/search-worker.js b/src/static/js/search-worker.js new file mode 100644 index 00000000..7932655b --- /dev/null +++ b/src/static/js/search-worker.js @@ -0,0 +1,92 @@ +import {makeSearchIndexes} from '../shared-util/searchSchema.js'; +import {withEntries} from '../shared-util/sugar.js'; + +import FlexSearch from '../lib/flexsearch/flexsearch.bundle.module.min.js'; + +let status = null; + +onmessage = handleWindowMessage; + +postStatus('alive'); + +const indexes = + makeSearchIndexes(FlexSearch); + +const searchData = + await fetch('/search-data/index.json') + .then(resp => resp.json()); + +// If this fails, it's because an outdated index was cached. +// TODO: If this fails, try again once with a cache busting url. +for (const [indexName, indexData] of Object.entries(searchData)) { + for (const [key, value] of Object.entries(indexData)) { + indexes[indexName].import(key, value); + } +} + +postStatus('ready'); + +function handleWindowMessage(message) { + switch (message.data.kind) { + case 'action': + handleWindowActionMessage(message); + break; + + default: + console.warn(`Unknown message kind -> to search worker:`, message.data); + break; + } +} + +async function handleWindowActionMessage(message) { + const {id} = message.data; + + if (!id) { + console.warn(`Action without id -> to search worker:`, message.data); + return; + } + + if (status !== 'ready') { + return postActionResult(id, 'reject', 'not ready'); + } + + let value; + + switch (message.data.action) { + case 'search': + value = await performSearch(message.data.options); + break; + + default: + console.warn(`Unknown action "${message.data.action}" -> to search worker:`, message.data); + return postActionResult(id, 'reject', 'unknown action'); + } + + await postActionResult(id, 'resolve', value); +} + +function postStatus(newStatus) { + status = newStatus; + postMessage({ + kind: 'status', + status: newStatus, + }); +} + +function postActionResult(id, status, value) { + postMessage({ + kind: 'result', + id, + status, + value, + }); +} + +function performSearch({query, options}) { + return ( + withEntries(indexes, entries => entries + .map(([indexName, index]) => [ + indexName, + index.search(query, options), + ]))); +} |