Initial buggy implementation of search backend
This commit is contained in:
parent
4cb57e84d6
commit
54b1b9f744
|
@ -0,0 +1,122 @@
|
||||||
|
/**
|
||||||
|
* Lunr-based searching
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* <meta name="search:index" content="https://search.devhints.io/index.json">
|
||||||
|
*
|
||||||
|
* s = new Search()
|
||||||
|
* s.inferFromMeta()
|
||||||
|
* s.search('hello').then(() => ...)
|
||||||
|
*
|
||||||
|
* s.loadFromData({ index, store })
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Search {
|
||||||
|
constructor (opts) {
|
||||||
|
const once = require('once')
|
||||||
|
const Emitter = require('events')
|
||||||
|
|
||||||
|
this.indexPath = opts && opts.index
|
||||||
|
this.load = once(this.load)
|
||||||
|
this.index = null
|
||||||
|
this.store = null
|
||||||
|
this.emitter = new Emitter()
|
||||||
|
}
|
||||||
|
|
||||||
|
load () {
|
||||||
|
return this.loadRemote()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infers `indexPath` from meta tags.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inferFromMeta () {
|
||||||
|
// Safeguard, in case we're not loaded in a browser context
|
||||||
|
if (typeof document === 'undefined') return this
|
||||||
|
|
||||||
|
const meta = document.querySelector('meta[name="search:index"]')
|
||||||
|
if (!meta) return this
|
||||||
|
|
||||||
|
const value = meta.getAttribute('content')
|
||||||
|
this.indexPath = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the search index remotely (via `indexPath`).
|
||||||
|
*/
|
||||||
|
|
||||||
|
loadRemote () {
|
||||||
|
return window.fetch(this.indexPath)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
this.loadFromData(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the search index locally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
loadFromData (data) {
|
||||||
|
const lunr = require('lunr')
|
||||||
|
|
||||||
|
const { index, store } = data
|
||||||
|
this.index = lunr.Index.load(index)
|
||||||
|
this.store = store
|
||||||
|
this.emitter.emit('load')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits until the data is loaded, then resolves.
|
||||||
|
*
|
||||||
|
* - When called when the data is still loading, it'll wait until the data is
|
||||||
|
* loaded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
loaded () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (this.index) return resolve(this)
|
||||||
|
|
||||||
|
this.emitter.on('load', () => {
|
||||||
|
resolve(this)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.load()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Searches for keywords.
|
||||||
|
*/
|
||||||
|
|
||||||
|
async search (keywords) {
|
||||||
|
await this.loaded()
|
||||||
|
const results = this.index.search(keywords)
|
||||||
|
const fullResults = results.map(result => {
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
object: this.store[result.ref]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return fullResults
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The primary instance
|
||||||
|
*/
|
||||||
|
|
||||||
|
const search = new Search().inferFromMeta()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Export
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
Search,
|
||||||
|
search
|
||||||
|
}
|
|
@ -38,6 +38,8 @@
|
||||||
"hint.css": "2.5.0",
|
"hint.css": "2.5.0",
|
||||||
"isotope-layout": "3.0.4",
|
"isotope-layout": "3.0.4",
|
||||||
"jquery": "3.2.1",
|
"jquery": "3.2.1",
|
||||||
|
"lunr": "2.1.4",
|
||||||
|
"once": "1.4.0",
|
||||||
"onmount": "1.3.0",
|
"onmount": "1.3.0",
|
||||||
"prismjs": "1.8.1",
|
"prismjs": "1.8.1",
|
||||||
"sanitize.css": "5.0.0"
|
"sanitize.css": "5.0.0"
|
||||||
|
|
|
@ -4536,6 +4536,10 @@ lru-cache@^4.0.1:
|
||||||
pseudomap "^1.0.2"
|
pseudomap "^1.0.2"
|
||||||
yallist "^2.1.2"
|
yallist "^2.1.2"
|
||||||
|
|
||||||
|
lunr@2.1.4:
|
||||||
|
version "2.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.1.4.tgz#52be0a9d068321909a7fb46575620e24417d5591"
|
||||||
|
|
||||||
macaddress@^0.2.8:
|
macaddress@^0.2.8:
|
||||||
version "0.2.8"
|
version "0.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
|
resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
|
||||||
|
@ -4980,7 +4984,7 @@ on-finished@~2.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ee-first "1.1.1"
|
ee-first "1.1.1"
|
||||||
|
|
||||||
once@^1.3.0, once@^1.3.3, once@^1.4.0:
|
once@1.4.0, once@^1.3.0, once@^1.3.3, once@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in New Issue