I started an implementation of something similar, but used Webworkers posting results back and forth for asynchronous searching in the browser.
Mine was a mess and didn't work ultimately, but I wanted to suggest it here in case there was interest in it. It really helped in larger datasets in my testing.
Hey @oliverseal, one should definitely be able to wrap Fuse in a WebWorker, and pass the results, possibly like this:
example.html (the main page)
var fuseWorker = new Worker("fuse_worker.js")
fuseWorker.onmessage = function(event) {
// event.data contains the search results
};
// Post a message to the worker, with the search string
fuseWorker.postMessage("blah");
fuse_worker.js (the worker)
// Fuse object should also be in this file
var fuse = new Fuse(list, options);
onmessage = function (event) {
// event.data is the search string
var result = fuse.search(event.data);
postMessage(result);
};
Hello there!
6 years after the issue/question is closed :) ... bare with me. Just letting it there for future reference.
Here is a working template for
dependency workerize that makes it easy to setup the worker and use it
import workerize from 'workerize';
// script string for creating inline fuse search engine worker
const workerizedFuse = `
// load Fuse library (browser prod build)
importScripts(self.location.origin + '/search/fuse.basic.min.js');
let _fuseOptions = null;
let _fuseIndex = null;
let _fuseInstance = null;
export function init(fuseIndexData, fuseOptions) {
_fuseOptions = fuseOptions || { keys: [] };
_fuseIndex = self.Fuse.createIndex(fuseOptions.keys, fuseIndexData);
_fuseInstance = new self.Fuse(fuseIndexData, _fuseOptions, _fuseIndex);
}
export function search(query) {
if(!_fuseInstance) throw new Error('worker fuse instance must be initiated first with index and options');
return _fuseInstance.search(query);
}
`;
class StaticSearch {
constructor(indexDataURL, options) {
this.fuseIndexURL = indexDataURL;
this.indexOptions = options || { keys: [] };
this.workerBee = null;
}
async init() {
const fuseIndexData = await fetch(this.fuseIndexURL).then(resp => resp.json())
this.workerBee = workerize(workerizedFuse);
this.workerBee.init(fuseIndexData, this.indexOptions);
}
async search(query) {
// first search triggers fuse setup
if(!this.workerBee) await this.init().catch(err => console.warn('an error occurred when instantiating workerized fuse search engine', err));
return this.workerBee.search(query);
}
}
export default StaticSearch;
Usage
import StaticSearch from "workerized-fuse";
const searchEngine = new StaticSearch('/search/fuse-index.json', { keys: ['title', 'author.firstName'] })
const results = await searchEngine.search(query);
Most helpful comment
Hey @oliverseal, one should definitely be able to wrap Fuse in a WebWorker, and pass the results, possibly like this:
example.html (the main page)
fuse_worker.js (the worker)