src/completer.js
// @flow
import EventEmitter from "eventemitter3"
import Query from "./query"
import SearchResult from "./search_result"
import Strategy from "./strategy"
const CALLBACK_METHODS = ["handleQueryResult"]
/**
* Complete engine.
*/
export default class Completer extends EventEmitter {
strategies: Strategy[]
constructor() {
super()
this.strategies = []
CALLBACK_METHODS.forEach(method => {
;(this: any)[method] = (this: any)[method].bind(this)
})
}
/**
* @return {this}
*/
destroy() {
this.strategies.forEach(strategy => strategy.destroy())
return this
}
/**
* Register a strategy to the completer.
*
* @return {this}
*/
registerStrategy(strategy: Strategy) {
this.strategies.push(strategy)
return this
}
/**
* @param {string} text - Head to input cursor.
*/
run(text: string): void {
const query = this.extractQuery(text)
if (query) {
query.execute(this.handleQueryResult)
} else {
this.handleQueryResult([])
}
}
/**
* Find a query, which matches to the given text.
*
* @private
*/
extractQuery(text: string) {
for (let i = 0; i < this.strategies.length; i++) {
const query = Query.build(this.strategies[i], text)
if (query) {
return query
}
}
return null
}
/**
* Callbacked by {@link Query#execute}.
*
* @private
*/
handleQueryResult(searchResults: SearchResult[]) {
this.emit("hit", { searchResults })
}
}