Initial buggy implementation of search backend

This commit is contained in:
Rico Sta. Cruz 2017-10-23 13:38:51 +08:00
parent 4cb57e84d6
commit 54b1b9f744
No known key found for this signature in database
GPG Key ID: CAAD38AE2962619A
3 changed files with 129 additions and 1 deletions

122
_js/search/index.js Normal file
View File

@ -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
}

View File

@ -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"

View File

@ -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: