synchronous-autocomplete
Advanced tools
Comparing version 0.1.0 to 1.0.0
82
build.js
@@ -1,28 +0,70 @@ | ||
'use strict' | ||
'use strict'; | ||
const buildIndexes = (tokenize, items) => { | ||
const tokens = Object.create(null) | ||
const weights = Object.create(null) | ||
const nrOfTokens = Object.create(null) | ||
var buildIndexes = function buildIndexes(tokenize, items) { | ||
var tokens = Object.create(null); | ||
var weights = Object.create(null); | ||
var nrOfTokens = Object.create(null); | ||
for (let item of items) { | ||
const tokensOfItem = tokenize(item.name) | ||
for (let token of tokensOfItem) { | ||
if (!Array.isArray(tokens[token])) tokens[token] = [] | ||
tokens[token].push(item.id) | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = items[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var item = _step.value; | ||
var tokensOfItem = tokenize(item.name); | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
try { | ||
for (var _iterator2 = tokensOfItem[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var _token = _step2.value; | ||
if (!Array.isArray(tokens[_token])) tokens[_token] = []; | ||
if (!tokens[_token].includes(item.id)) tokens[_token].push(item.id); | ||
} | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
_iterator2.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
} | ||
} | ||
} | ||
weights[item.id] = item.weight; | ||
nrOfTokens[item.id] = tokensOfItem.length; | ||
} | ||
weights[item.id] = item.weight | ||
nrOfTokens[item.id] = tokensOfItem.length | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
const scores = Object.create(null) | ||
for (let token in tokens) { | ||
const nrOfItemsForToken = tokens[token].length | ||
scores[token] = nrOfItemsForToken / items.length | ||
var scores = Object.create(null); | ||
for (var token in tokens) { | ||
var nrOfItemsForToken = tokens[token].length; | ||
scores[token] = nrOfItemsForToken / items.length; | ||
} | ||
return {tokens, scores, weights, nrOfTokens} | ||
} | ||
return { tokens: tokens, scores: scores, weights: weights, nrOfTokens: nrOfTokens }; | ||
}; | ||
module.exports = buildIndexes | ||
module.exports = buildIndexes; |
170
index.js
@@ -1,18 +0,39 @@ | ||
'use strict' | ||
'use strict'; | ||
const hifo = require('hifo') | ||
const leven = require('leven') | ||
var hifo = require('hifo'); | ||
var leven = require('leven'); | ||
const createAutocomplete = (tokens, scores, weights, nrOfTokens, tokenize) => { | ||
const byFragment = (fragment, completion, fuzzy) => { | ||
const results = {} | ||
const l = fragment.length | ||
var createAutocomplete = function createAutocomplete(tokens, scores, weights, nrOfTokens, tokenize) { | ||
var byFragment = function byFragment(fragment, completion, fuzzy) { | ||
var results = {}; | ||
var l = fragment.length; | ||
if (tokens[fragment]) { | ||
const relevance = 1 + scores[fragment] + Math.sqrt(fragment.length) | ||
var relevance = 1 + scores[fragment] + Math.sqrt(fragment.length); | ||
for (let id of tokens[fragment]) { | ||
if (!results[id] || !results[id] > relevance) { | ||
results[id] = relevance | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = tokens[fragment][Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var id = _step.value; | ||
if (!results[id] || !results[id] > relevance) { | ||
results[id] = relevance; | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
@@ -22,19 +43,40 @@ } | ||
if (completion || fuzzy) { | ||
for (let t in tokens) { | ||
if (fragment === t) continue // has been dealt with above | ||
for (var t in tokens) { | ||
if (fragment === t) continue; // has been dealt with above | ||
let relevance | ||
let distance | ||
var _relevance = void 0; | ||
var distance = void 0; | ||
// add-one smoothing | ||
if (completion && t.length > fragment.length && fragment === t.slice(0, l)) { | ||
relevance = 1 + scores[t] + fragment.length / t.length | ||
_relevance = 1 + scores[t] + fragment.length / t.length; | ||
} else if (fuzzy && (distance = leven(fragment, t)) <= 3) { | ||
relevance = (1 + scores[t]) / (distance + 1) | ||
} else continue | ||
_relevance = (1 + scores[t]) / (distance + 1); | ||
} else continue; | ||
for (let id of tokens[t]) { | ||
if (!results[id] || !results[id] > relevance) { | ||
results[id] = relevance | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
try { | ||
for (var _iterator2 = tokens[t][Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var _id = _step2.value; | ||
if (!results[_id] || !results[_id] > _relevance) { | ||
results[_id] = _relevance; | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
_iterator2.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
} | ||
} | ||
} | ||
@@ -44,44 +86,70 @@ } | ||
return results | ||
} | ||
return results; | ||
}; | ||
const autocomplete = (query, limit = 6, fuzzy = false, completion = true) => { | ||
if (query === '') return [] | ||
var autocomplete = function autocomplete(query) { | ||
var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 6; | ||
var fuzzy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; | ||
var completion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; | ||
const data = Object.create(null) | ||
for (let fragment of tokenize(query)) { | ||
data[fragment] = byFragment(fragment, completion, fuzzy) | ||
} | ||
if (query === '') return []; | ||
const totalRelevance = (id) => { | ||
let r = 1 / nrOfTokens[id] | ||
for (let fragment in data) { | ||
if (!data[fragment][id]) return false | ||
r *= data[fragment][id] | ||
var data = Object.create(null); | ||
var _iteratorNormalCompletion3 = true; | ||
var _didIteratorError3 = false; | ||
var _iteratorError3 = undefined; | ||
try { | ||
for (var _iterator3 = tokenize(query)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | ||
var fragment = _step3.value; | ||
data[fragment] = byFragment(fragment, completion, fuzzy); | ||
} | ||
return r | ||
} catch (err) { | ||
_didIteratorError3 = true; | ||
_iteratorError3 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion3 && _iterator3.return) { | ||
_iterator3.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError3) { | ||
throw _iteratorError3; | ||
} | ||
} | ||
} | ||
const results = Object.create(null) | ||
for (let fragment in data) { | ||
for (let id in data[fragment]) { | ||
if (id in results) continue | ||
var totalRelevance = function totalRelevance(id) { | ||
var r = 1 / nrOfTokens[id]; | ||
for (var _fragment in data) { | ||
if (!data[_fragment][id]) return false; | ||
r *= data[_fragment][id]; | ||
} | ||
return r; | ||
}; | ||
const relevance = totalRelevance(id) | ||
if (relevance === false) continue | ||
var results = Object.create(null); | ||
for (var _fragment2 in data) { | ||
for (var id in data[_fragment2]) { | ||
if (id in results) continue; | ||
const score = relevance * Math.pow(weights[id], 1/3) | ||
results[id] = {id, relevance, score} | ||
var relevance = totalRelevance(id); | ||
if (relevance === false) continue; | ||
var score = relevance * Math.pow(weights[id], 1 / 3); | ||
results[id] = { id: id, relevance: relevance, score: score, weight: weights[id] }; | ||
} | ||
} | ||
const relevant = hifo(hifo.highest('score'), limit || 6) | ||
for (let id in results) relevant.add(results[id]) | ||
return relevant.data | ||
} | ||
var relevant = hifo(hifo.highest('score'), limit || 6); | ||
for (var _id2 in results) { | ||
relevant.add(results[_id2]); | ||
}return relevant.data; | ||
}; | ||
autocomplete.byFragment = byFragment | ||
return autocomplete | ||
} | ||
autocomplete.byFragment = byFragment; | ||
return autocomplete; | ||
}; | ||
module.exports = createAutocomplete | ||
module.exports = createAutocomplete; |
{ | ||
"name": "synchronous-autocomplete", | ||
"description": "Fast, simple autocompletion.", | ||
"version": "0.1.0", | ||
"version": "1.0.0", | ||
"main": "index.js", | ||
"files": [ | ||
"index.js", | ||
"build.js" | ||
"build.js", | ||
"src" | ||
], | ||
@@ -28,2 +29,4 @@ "keywords": [ | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"babel-preset-env": "^1.6.1", | ||
"lodash.sortby": "^4.7.0", | ||
@@ -35,5 +38,6 @@ "normalize-for-search": "^2.0.1", | ||
"scripts": { | ||
"build": "babel src --presets env --out-dir .", | ||
"test": "node test.js | tap-min", | ||
"prepublishOnly": "npm test" | ||
"prepublishOnly": "npm run build && npm test" | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
14653
7
275
0
6
1