Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@leeoniya/ufuzzy

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@leeoniya/ufuzzy - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

99

dist/uFuzzy.cjs.js

@@ -7,3 +7,3 @@ /**

* A tiny, efficient fuzzy matcher that doesn't suck
* https://github.com/leeoniya/uFuzzy (v1.0.0)
* https://github.com/leeoniya/uFuzzy (v1.0.1)
*/

@@ -179,3 +179,3 @@

const prepQuery = (needle, capt = 0) => {
const prepQuery = (needle, capt = 0, exactParts, interOR = false) => {
// split on punct, whitespace, num-alpha, and upper-lower boundaries

@@ -189,3 +189,3 @@ let parts = split(needle);

if (intraMode == 1) {
reTpl = parts.map(p => {
reTpl = parts.map((p, pi) => {
let {

@@ -199,3 +199,3 @@ intraSlice,

if (intraIns + intraSub + intraTrn + intraDel == 0)
if (intraIns + intraSub + intraTrn + intraDel == 0 || exactParts?.[pi] == 1)
return p;

@@ -246,3 +246,7 @@

return '(?:' + p + '|' + variants.join('|') + ')';
let reTpl = '(?:' + p + '|' + variants.join('|') + ')';
// console.log(reTpl);
return reTpl;
});

@@ -260,3 +264,3 @@ }

reTpl = parts.map(p => p.split('').map((c, i, chars) => {
reTpl = parts.map((p, pi) => exactParts?.[pi] == 1 ? p : p.split('').map((c, i, chars) => {
// neg lookahead to prefer matching 'Test' instead of 'tTest' in ManifestTest or fittest

@@ -282,17 +286,17 @@ // but skip when search term contains leading repetition (aardvark, aaa)

if (capt > 0) {
// sadly, we also have to capture the inter-term junk via parenth-wrapping .*?
// to accum other capture groups' indices for \b boosting during scoring
reTpl = '(' + reTpl.join(')(' + interCharsTpl + ')(') + ')';
if (interOR) {
// this is basically for doing .matchAll() occurence counting and highlihting without needing permuted ooo needles
reTpl = preTpl + '(' + reTpl.join(')' + sufTpl + '|' + preTpl + '(') + ')' + sufTpl;
}
else {
// sadly, we also have to capture the inter-term junk via parenth-wrapping .*?
// to accum other capture groups' indices for \b boosting during scoring
reTpl = '(' + reTpl.join(')(' + interCharsTpl + ')(') + ')';
reTpl = '(.?' + preTpl + ')' + reTpl + '(' + sufTpl + '.*)'; // nit: trailing capture here assumes interIns = Inf
}
}
else
else {
reTpl = reTpl.join(interCharsTpl);
if (capt > 0) {
if (interLft == 2)
reTpl = '(' + preTpl + ')' + reTpl + '(' + sufTpl + ')';
else
reTpl = '(.?)' + reTpl + '(.?)';
reTpl = preTpl + reTpl + sufTpl;
}
else
reTpl = preTpl + reTpl + sufTpl;

@@ -331,4 +335,4 @@ // console.log(reTpl);

let [query, parts] = prepQuery(needle, 1);
let [queryR] = prepQuery(needle, 2);
let partsLen = parts.length;
let [queryR] = prepQuery(needle, 2);

@@ -395,2 +399,5 @@ let len = idxs.length;

// will be populated if we need to re-generate a query with some exact terms
let useExactParts = null;
for (let j = 0, k = 2; j < partsLen; j++, k+=2) {

@@ -403,2 +410,49 @@ let group = m[k].toLowerCase();

// this won't handle the case when an exact match exists across the boundary of the current group and the next junk
// e.g. blob,ob when searching for 'bob' but finding the earlier `blob` (with extra insertion)
if (!fullMatch && groupLen >= termLen && m[k+1].length >= termLen) {
// probe for exact match in inter junk
let idxOf = m[k+1].toLowerCase().indexOf(term);
if (idxOf > -1) {
// so here we have three options:
// 1. mutate the current match to be better.
// this doesn't help the range regex below, which would need different adjustement logic, since
// its capture groups are more granular
// 2. re-generate a new regex with some terms flagged as exact rather than a group of alterations
// this is more expensive since we need to re-process, but will be seamless for range query,
// but would require popping out of this loop and throwing away exisitng info counters
// 3. do a combo of the above
// we can stay in this loop, but also gen a more explicit ranges regex that will result in the
// better match
// this whole section probably risks violating interIns < Inf, since better terms might be too far away
// we could test for this here to choose not to re-process, but it's pretty unusual to reduce interIns
// (usually to only accept tighter matches). the match improvement here is likely better.
// debugger;
// shift the current group into the prior junk, adjust idxAcc & start
let prepend = m[k] + m[k+1].slice(0, idxOf);
m[k-1] += prepend;
idxAcc += prepend.length;
if (j == 0)
start = idxAcc;
// update current group and next junk
m[k] = m[k+1].slice(idxOf, idxOf + termLen);
m[k+1] = m[k+1].slice(idxOf + termLen);
group = m[k].toLowerCase();
groupLen = termLen;
fullMatch = true;
if (useExactParts == null)
useExactParts = Array(partsLen).fill(0);
useExactParts[j] = 1;
}
}
if (mayDiscard || fullMatch) {

@@ -479,2 +533,4 @@ // does group's left and/or right land on \b

if (!disc) {
let idxQueryR = useExactParts != null ? prepQuery(needle, 2, useExactParts)[0] : queryR;
info.idx[ii] = idxs[i];

@@ -494,3 +550,3 @@ info.interLft2[ii] = lft2;

// ranges
let m = mhstr.match(queryR);
let m = mhstr.match(idxQueryR);
let ranges = info.ranges[ii] = [];

@@ -580,2 +636,5 @@

// interOR
// console.log(prepQuery(needle, 1, null, true));
// non-ooo or ooo w/single term

@@ -582,0 +641,0 @@ if (needles == null) {

@@ -7,3 +7,3 @@ /**

* A tiny, efficient fuzzy matcher that doesn't suck
* https://github.com/leeoniya/uFuzzy (v1.0.0)
* https://github.com/leeoniya/uFuzzy (v1.0.1)
*/

@@ -177,3 +177,3 @@

const prepQuery = (needle, capt = 0) => {
const prepQuery = (needle, capt = 0, exactParts, interOR = false) => {
// split on punct, whitespace, num-alpha, and upper-lower boundaries

@@ -187,3 +187,3 @@ let parts = split(needle);

if (intraMode == 1) {
reTpl = parts.map(p => {
reTpl = parts.map((p, pi) => {
let {

@@ -197,3 +197,3 @@ intraSlice,

if (intraIns + intraSub + intraTrn + intraDel == 0)
if (intraIns + intraSub + intraTrn + intraDel == 0 || exactParts?.[pi] == 1)
return p;

@@ -244,3 +244,7 @@

return '(?:' + p + '|' + variants.join('|') + ')';
let reTpl = '(?:' + p + '|' + variants.join('|') + ')';
// console.log(reTpl);
return reTpl;
});

@@ -258,3 +262,3 @@ }

reTpl = parts.map(p => p.split('').map((c, i, chars) => {
reTpl = parts.map((p, pi) => exactParts?.[pi] == 1 ? p : p.split('').map((c, i, chars) => {
// neg lookahead to prefer matching 'Test' instead of 'tTest' in ManifestTest or fittest

@@ -280,17 +284,17 @@ // but skip when search term contains leading repetition (aardvark, aaa)

if (capt > 0) {
// sadly, we also have to capture the inter-term junk via parenth-wrapping .*?
// to accum other capture groups' indices for \b boosting during scoring
reTpl = '(' + reTpl.join(')(' + interCharsTpl + ')(') + ')';
if (interOR) {
// this is basically for doing .matchAll() occurence counting and highlihting without needing permuted ooo needles
reTpl = preTpl + '(' + reTpl.join(')' + sufTpl + '|' + preTpl + '(') + ')' + sufTpl;
}
else {
// sadly, we also have to capture the inter-term junk via parenth-wrapping .*?
// to accum other capture groups' indices for \b boosting during scoring
reTpl = '(' + reTpl.join(')(' + interCharsTpl + ')(') + ')';
reTpl = '(.?' + preTpl + ')' + reTpl + '(' + sufTpl + '.*)'; // nit: trailing capture here assumes interIns = Inf
}
}
else
else {
reTpl = reTpl.join(interCharsTpl);
if (capt > 0) {
if (interLft == 2)
reTpl = '(' + preTpl + ')' + reTpl + '(' + sufTpl + ')';
else
reTpl = '(.?)' + reTpl + '(.?)';
reTpl = preTpl + reTpl + sufTpl;
}
else
reTpl = preTpl + reTpl + sufTpl;

@@ -329,4 +333,4 @@ // console.log(reTpl);

let [query, parts] = prepQuery(needle, 1);
let [queryR] = prepQuery(needle, 2);
let partsLen = parts.length;
let [queryR] = prepQuery(needle, 2);

@@ -393,2 +397,5 @@ let len = idxs.length;

// will be populated if we need to re-generate a query with some exact terms
let useExactParts = null;
for (let j = 0, k = 2; j < partsLen; j++, k+=2) {

@@ -401,2 +408,49 @@ let group = m[k].toLowerCase();

// this won't handle the case when an exact match exists across the boundary of the current group and the next junk
// e.g. blob,ob when searching for 'bob' but finding the earlier `blob` (with extra insertion)
if (!fullMatch && groupLen >= termLen && m[k+1].length >= termLen) {
// probe for exact match in inter junk
let idxOf = m[k+1].toLowerCase().indexOf(term);
if (idxOf > -1) {
// so here we have three options:
// 1. mutate the current match to be better.
// this doesn't help the range regex below, which would need different adjustement logic, since
// its capture groups are more granular
// 2. re-generate a new regex with some terms flagged as exact rather than a group of alterations
// this is more expensive since we need to re-process, but will be seamless for range query,
// but would require popping out of this loop and throwing away exisitng info counters
// 3. do a combo of the above
// we can stay in this loop, but also gen a more explicit ranges regex that will result in the
// better match
// this whole section probably risks violating interIns < Inf, since better terms might be too far away
// we could test for this here to choose not to re-process, but it's pretty unusual to reduce interIns
// (usually to only accept tighter matches). the match improvement here is likely better.
// debugger;
// shift the current group into the prior junk, adjust idxAcc & start
let prepend = m[k] + m[k+1].slice(0, idxOf);
m[k-1] += prepend;
idxAcc += prepend.length;
if (j == 0)
start = idxAcc;
// update current group and next junk
m[k] = m[k+1].slice(idxOf, idxOf + termLen);
m[k+1] = m[k+1].slice(idxOf + termLen);
group = m[k].toLowerCase();
groupLen = termLen;
fullMatch = true;
if (useExactParts == null)
useExactParts = Array(partsLen).fill(0);
useExactParts[j] = 1;
}
}
if (mayDiscard || fullMatch) {

@@ -477,2 +531,4 @@ // does group's left and/or right land on \b

if (!disc) {
let idxQueryR = useExactParts != null ? prepQuery(needle, 2, useExactParts)[0] : queryR;
info.idx[ii] = idxs[i];

@@ -492,3 +548,3 @@ info.interLft2[ii] = lft2;

// ranges
let m = mhstr.match(queryR);
let m = mhstr.match(idxQueryR);
let ranges = info.ranges[ii] = [];

@@ -578,2 +634,5 @@

// interOR
// console.log(prepQuery(needle, 1, null, true));
// non-ooo or ooo w/single term

@@ -580,0 +639,0 @@ if (needles == null) {

@@ -7,3 +7,3 @@ /**

* A tiny, efficient fuzzy matcher that doesn't suck
* https://github.com/leeoniya/uFuzzy (v1.0.0)
* https://github.com/leeoniya/uFuzzy (v1.0.1)
*/

@@ -180,3 +180,3 @@

const prepQuery = (needle, capt = 0) => {
const prepQuery = (needle, capt = 0, exactParts, interOR = false) => {
// split on punct, whitespace, num-alpha, and upper-lower boundaries

@@ -190,3 +190,3 @@ let parts = split(needle);

if (intraMode == 1) {
reTpl = parts.map(p => {
reTpl = parts.map((p, pi) => {
let {

@@ -200,3 +200,3 @@ intraSlice,

if (intraIns + intraSub + intraTrn + intraDel == 0)
if (intraIns + intraSub + intraTrn + intraDel == 0 || exactParts?.[pi] == 1)
return p;

@@ -247,3 +247,7 @@

return '(?:' + p + '|' + variants.join('|') + ')';
let reTpl = '(?:' + p + '|' + variants.join('|') + ')';
// console.log(reTpl);
return reTpl;
});

@@ -261,3 +265,3 @@ }

reTpl = parts.map(p => p.split('').map((c, i, chars) => {
reTpl = parts.map((p, pi) => exactParts?.[pi] == 1 ? p : p.split('').map((c, i, chars) => {
// neg lookahead to prefer matching 'Test' instead of 'tTest' in ManifestTest or fittest

@@ -283,17 +287,17 @@ // but skip when search term contains leading repetition (aardvark, aaa)

if (capt > 0) {
// sadly, we also have to capture the inter-term junk via parenth-wrapping .*?
// to accum other capture groups' indices for \b boosting during scoring
reTpl = '(' + reTpl.join(')(' + interCharsTpl + ')(') + ')';
if (interOR) {
// this is basically for doing .matchAll() occurence counting and highlihting without needing permuted ooo needles
reTpl = preTpl + '(' + reTpl.join(')' + sufTpl + '|' + preTpl + '(') + ')' + sufTpl;
}
else {
// sadly, we also have to capture the inter-term junk via parenth-wrapping .*?
// to accum other capture groups' indices for \b boosting during scoring
reTpl = '(' + reTpl.join(')(' + interCharsTpl + ')(') + ')';
reTpl = '(.?' + preTpl + ')' + reTpl + '(' + sufTpl + '.*)'; // nit: trailing capture here assumes interIns = Inf
}
}
else
else {
reTpl = reTpl.join(interCharsTpl);
if (capt > 0) {
if (interLft == 2)
reTpl = '(' + preTpl + ')' + reTpl + '(' + sufTpl + ')';
else
reTpl = '(.?)' + reTpl + '(.?)';
reTpl = preTpl + reTpl + sufTpl;
}
else
reTpl = preTpl + reTpl + sufTpl;

@@ -332,4 +336,4 @@ // console.log(reTpl);

let [query, parts] = prepQuery(needle, 1);
let [queryR] = prepQuery(needle, 2);
let partsLen = parts.length;
let [queryR] = prepQuery(needle, 2);

@@ -396,2 +400,5 @@ let len = idxs.length;

// will be populated if we need to re-generate a query with some exact terms
let useExactParts = null;
for (let j = 0, k = 2; j < partsLen; j++, k+=2) {

@@ -404,2 +411,49 @@ let group = m[k].toLowerCase();

// this won't handle the case when an exact match exists across the boundary of the current group and the next junk
// e.g. blob,ob when searching for 'bob' but finding the earlier `blob` (with extra insertion)
if (!fullMatch && groupLen >= termLen && m[k+1].length >= termLen) {
// probe for exact match in inter junk
let idxOf = m[k+1].toLowerCase().indexOf(term);
if (idxOf > -1) {
// so here we have three options:
// 1. mutate the current match to be better.
// this doesn't help the range regex below, which would need different adjustement logic, since
// its capture groups are more granular
// 2. re-generate a new regex with some terms flagged as exact rather than a group of alterations
// this is more expensive since we need to re-process, but will be seamless for range query,
// but would require popping out of this loop and throwing away exisitng info counters
// 3. do a combo of the above
// we can stay in this loop, but also gen a more explicit ranges regex that will result in the
// better match
// this whole section probably risks violating interIns < Inf, since better terms might be too far away
// we could test for this here to choose not to re-process, but it's pretty unusual to reduce interIns
// (usually to only accept tighter matches). the match improvement here is likely better.
// debugger;
// shift the current group into the prior junk, adjust idxAcc & start
let prepend = m[k] + m[k+1].slice(0, idxOf);
m[k-1] += prepend;
idxAcc += prepend.length;
if (j == 0)
start = idxAcc;
// update current group and next junk
m[k] = m[k+1].slice(idxOf, idxOf + termLen);
m[k+1] = m[k+1].slice(idxOf + termLen);
group = m[k].toLowerCase();
groupLen = termLen;
fullMatch = true;
if (useExactParts == null)
useExactParts = Array(partsLen).fill(0);
useExactParts[j] = 1;
}
}
if (mayDiscard || fullMatch) {

@@ -480,2 +534,4 @@ // does group's left and/or right land on \b

if (!disc) {
let idxQueryR = useExactParts != null ? prepQuery(needle, 2, useExactParts)[0] : queryR;
info.idx[ii] = idxs[i];

@@ -495,3 +551,3 @@ info.interLft2[ii] = lft2;

// ranges
let m = mhstr.match(queryR);
let m = mhstr.match(idxQueryR);
let ranges = info.ranges[ii] = [];

@@ -581,2 +637,5 @@

// interOR
// console.log(prepQuery(needle, 1, null, true));
// non-ooo or ooo w/single term

@@ -583,0 +642,0 @@ if (needles == null) {

@@ -1,2 +0,2 @@

/*! https://github.com/leeoniya/uFuzzy (v1.0.0) */
var uFuzzy=function(){"use strict";const t=new Intl.Collator("en").compare,e=1/0,n={interSplit:"[^A-Za-z0-9]+",intraSplit:"[a-z][A-Z]",intraBound:"[A-Za-z][0-9]|[0-9][A-Za-z]|[a-z][A-Z]",interLft:0,interRgt:0,interChars:".",interIns:e,intraChars:"[a-z\\d]",intraIns:0,intraMode:0,intraSlice:[1,e],intraSub:0,intraTrn:0,intraDel:0,intraFilt:()=>!0,sort:(e,n)=>{let{idx:l,chars:r,terms:i,interLft2:s,interLft1:a,start:h,intraIns:g,interIns:f}=e;return l.map(((t,e)=>e)).sort(((e,c)=>r[c]-r[e]||g[e]-g[c]||i[c]+s[c]+.5*a[c]-(i[e]+s[e]+.5*a[e])||f[e]-f[c]||h[e]-h[c]||t(n[l[e]],n[l[c]])))}},l=(t,n)=>0==n?"":1==n?t+"??":n==e?t+"*?":t+`{0,${n}}?`,r="(?:\\b|_)";function i(t){t=Object.assign({},n,t);const{interLft:e,interRgt:i,intraMode:s,intraSlice:h,intraIns:g,intraSub:f,intraTrn:c,intraDel:u,intraSplit:o,interSplit:p,intraBound:m,intraChars:b}=t;let{intraRules:S}=t;null==S&&(S=t=>{let e=n.intraSlice,l=0,r=0,i=0,s=0,a=t.length;return a>4?(e=h,l=g,r=f,i=c,s=u):3>a||(i=Math.min(c,1),4==a&&(l=Math.min(g,1))),{intraSlice:e,intraIns:l,intraSub:r,intraTrn:i,intraDel:s}});let I=!!o,R=RegExp(o,"g"),d=RegExp(p,"g"),x=RegExp("^"+p+"|"+p+"$","g");const A=t=>(t=t.replace(x,""),I&&(t=t.replace(R,(t=>t[0]+" "+t[1]))),t.split(d)),z=(n,a=0)=>{let h,f=A(n);if(1==s)h=f.map((t=>{let{intraSlice:e,intraIns:n,intraSub:r,intraTrn:i,intraDel:s}=S(t);if(n+r+i+s==0)return t;let[a,h]=e,g=t.slice(0,a),f=t.slice(h),c=t.slice(a,h);1==n&&1==g.length&&g!=c[0]&&(g+="(?!"+g+")");let u=c.length,o=[];if(r)for(let t=0;u>t;t++)o.push(g+c.slice(0,t)+b+c.slice(t+1)+f);if(i)for(let t=0;u-1>t;t++)c[t]!=c[t+1]&&o.push(g+c.slice(0,t)+c[t+1]+c[t]+c.slice(t+2)+f);if(s)for(let t=0;u>t;t++)o.push(g+c.slice(0,t+1)+"?"+c.slice(t+1)+f);if(n){let t=l(b,1);for(let e=0;u>e;e++)o.push(g+c.slice(0,e)+t+c.slice(e)+f)}return"(?:"+t+"|"+o.join("|")+")"}));else{let t=l(b,g);2==a&&g>0&&(t=")("+t+")("),h=f.map((e=>e.split("").map(((t,e,n)=>(1==g&&0==e&&n.length>1&&t[e]!=t[e+1]&&(t+="(?!"+t+")"),t))).join(t)))}let c=2==e?r:"",u=2==i?r:"",o=u+l(t.interChars,t.interIns)+c;return h=a>0?"("+h.join(")("+o+")(")+")":h.join(o),h=a>0?2==e?"("+c+")"+h+"("+u+")":"(.?)"+h+"(.?)":c+h+u,[RegExp(h,"i"),f]},E=(t,e,n)=>{let l=[],[r]=z(e);if(null!=n)for(let e=0;n.length>e;e++){let i=n[e];r.test(t[i])&&l.push(i)}else for(let e=0;t.length>e;e++)r.test(t[e])&&l.push(e);return l};let L=!!m,k=RegExp(p),y=RegExp(m);const C=(n,l,r)=>{let[s,a]=z(r,1),h=a.length,[g]=z(r,2),f=n.length,c=Array(f).fill(0),u={idx:Array(f),start:c.slice(),chars:c.slice(),terms:c.slice(),interIns:c.slice(),intraIns:c.slice(),interLft2:c.slice(),interRgt2:c.slice(),interLft1:c.slice(),interRgt1:c.slice(),ranges:Array(f)},o=1==e||1==i,p=0;for(let r=0;n.length>r;r++){let f=l[n[r]],c=f.match(s),m=c.index+c[1].length,b=m,S=!1,I=0,R=0,d=0,x=0,A=0,z=0,E=0,C=0;for(let n=0,l=2;h>n;n++,l+=2){let r=c[l].toLowerCase(),s=a[n],g=s.length,u=r.length,p=r==s;if(o||p){let t=b-1,n=b+u,l=!0,r=!0;if(-1==t||k.test(f[t]))p&&I++;else{if(2==e){S=!0;break}if(L&&y.test(f[t]+f[t+1]))p&&R++;else{if(1==e){S=!0;break}l=!1}}if(n==f.length||k.test(f[n]))p&&d++;else{if(2==i){S=!0;break}if(L&&y.test(f[n-1]+f[n]))p&&x++;else{if(1==i){S=!0;break}r=!1}}p&&(A+=g,l&&r&&z++)}if(u>g&&(C+=u-g),n>0&&(E+=c[l-1].length),!t.intraFilt(s,r,b)){S=!0;break}h-1>n&&(b+=u+c[l+1].length)}if(!S){u.idx[p]=n[r],u.interLft2[p]=I,u.interLft1[p]=R,u.interRgt2[p]=d,u.interRgt1[p]=x,u.chars[p]=A,u.terms[p]=z,u.interIns[p]=E,u.intraIns[p]=C,u.start[p]=m;let t=f.match(g),e=u.ranges[p]=[],l=t.index+t[1].length,i=l,s=l;for(let n=2;t.length>n;n++){let r=t[n].length;l+=r,n%2==0?s=l:r>0&&(e.push(i,s),i=s=l)}s>i&&e.push(i,s),p++}}if(n.length>p)for(let t in u)u[t]=u[t].slice(0,p);return u};return{search:(...e)=>((e,n,l=!1,r=1e3,i)=>{let s=null,h=null;if(l){let t=A(n);if(t.length>1){let n=t.slice().sort(((t,e)=>e.length-t.length));for(let t=0;n.length>t;t++){if(0==i?.length)return[[],null,null];i=E(e,n[t],i)}s=a(t).map((t=>t.join(" "))),h=[];let l=new Set;for(let t=0;s.length>t;t++)if(i.length>l.size){let n=i.filter((t=>!l.has(t))),r=E(e,s[t],n);for(let t=0;r.length>t;t++)l.add(r[t]);h.push(r)}else h.push([])}}null==s&&(s=[n],h=[i?.length>0?i:E(e,n)]);let g=null,f=null;if(r>=h.reduce(((t,e)=>t+e.length),0)){g={},f=[];for(let n=0;h.length>n;n++){let l=h[n];if(null==l||0==l.length)continue;let r=s[n],i=C(l,e,r),a=t.sort(i,e,r);if(n>0)for(let t=0;a.length>t;t++)a[t]+=f.length;for(let t in i)g[t]=(g[t]??[]).concat(i[t]);f=f.concat(a)}}return[[].concat(...h),g,f]})(...e),split:A,filter:E,info:C,sort:t.sort}}const s=(()=>{let t={A:"ÁÀÃÂÄĄ",a:"áàãâäą",E:"ÉÈÊËĖ",e:"éèêëę",I:"ÍÌÎÏĮ",i:"íìîïį",O:"ÓÒÔÕÖ",o:"óòôõö",U:"ÚÙÛÜŪŲ",u:"úùûüūų",C:"ÇČ",c:"çč",N:"Ñ",n:"ñ",S:"Š",s:"š"},e=new Map,n="";for(let l in t)t[l].split("").forEach((t=>{n+=t,e.set(t,l)}));let l=RegExp(`[${n}]`,"g");return t=>{let n=Array(t.length);for(let r=0;t.length>r;r++)n[r]=t[r].replace(l,(t=>e.get(t)));return n}})();function a(t){let e,n,l=(t=t.slice()).length,r=[t.slice()],i=Array(l).fill(0),s=1;for(;l>s;)s>i[s]?(e=s%2&&i[s],n=t[s],t[s]=t[e],t[e]=n,++i[s],s=1,r.push(t.slice())):(i[s]=0,++s);return r}const h=(t,e)=>e?`<mark>${t}</mark>`:t,g=(t,e)=>t+e;return i.latinize=s,i.permute=t=>a([...Array(t.length).keys()]).sort(((t,e)=>{for(let n=0;t.length>n;n++)if(t[n]!=e[n])return t[n]-e[n];return 0})).map((e=>e.map((e=>t[e])))),i.highlight=function(t,e,n=h,l="",r=g){l=r(l,n(t.substring(0,e[0]),!1))??l;for(let i=0;e.length>i;i+=2)l=r(l,n(t.substring(e[i],e[i+1]),!0))??l,e.length-3>i&&(l=r(l,n(t.substring(e[i+1],e[i+2]),!1))??l);return r(l,n(t.substring(e[e.length-1]),!1))??l},i}();
/*! https://github.com/leeoniya/uFuzzy (v1.0.1) */
var uFuzzy=function(){"use strict";const t=new Intl.Collator("en").compare,e=1/0,n={interSplit:"[^A-Za-z0-9]+",intraSplit:"[a-z][A-Z]",intraBound:"[A-Za-z][0-9]|[0-9][A-Za-z]|[a-z][A-Z]",interLft:0,interRgt:0,interChars:".",interIns:e,intraChars:"[a-z\\d]",intraIns:0,intraMode:0,intraSlice:[1,e],intraSub:0,intraTrn:0,intraDel:0,intraFilt:()=>!0,sort:(e,n)=>{let{idx:l,chars:r,terms:i,interLft2:s,interLft1:a,start:h,intraIns:f,interIns:g}=e;return l.map(((t,e)=>e)).sort(((e,c)=>r[c]-r[e]||f[e]-f[c]||i[c]+s[c]+.5*a[c]-(i[e]+s[e]+.5*a[e])||g[e]-g[c]||h[e]-h[c]||t(n[l[e]],n[l[c]])))}},l=(t,n)=>0==n?"":1==n?t+"??":n==e?t+"*?":t+`{0,${n}}?`,r="(?:\\b|_)";function i(t){t=Object.assign({},n,t);const{interLft:e,interRgt:i,intraMode:s,intraSlice:h,intraIns:f,intraSub:g,intraTrn:c,intraDel:o,intraSplit:u,interSplit:p,intraBound:m,intraChars:b}=t;let{intraRules:S}=t;null==S&&(S=t=>{let e=n.intraSlice,l=0,r=0,i=0,s=0,a=t.length;return a>4?(e=h,l=f,r=g,i=c,s=o):3>a||(i=Math.min(c,1),4==a&&(l=Math.min(f,1))),{intraSlice:e,intraIns:l,intraSub:r,intraTrn:i,intraDel:s}});let d=!!u,I=RegExp(u,"g"),R=RegExp(p,"g"),x=RegExp("^"+p+"|"+p+"$","g");const A=t=>(t=t.replace(x,""),d&&(t=t.replace(I,(t=>t[0]+" "+t[1]))),t.split(R)),L=(n,a=0,h,g=!1)=>{let c,o=A(n);if(1==s)c=o.map(((t,e)=>{let{intraSlice:n,intraIns:r,intraSub:i,intraTrn:s,intraDel:a}=S(t);if(r+i+s+a==0||1==h?.[e])return t;let[f,g]=n,c=t.slice(0,f),o=t.slice(g),u=t.slice(f,g);1==r&&1==c.length&&c!=u[0]&&(c+="(?!"+c+")");let p=u.length,m=[];if(i)for(let t=0;p>t;t++)m.push(c+u.slice(0,t)+b+u.slice(t+1)+o);if(s)for(let t=0;p-1>t;t++)u[t]!=u[t+1]&&m.push(c+u.slice(0,t)+u[t+1]+u[t]+u.slice(t+2)+o);if(a)for(let t=0;p>t;t++)m.push(c+u.slice(0,t+1)+"?"+u.slice(t+1)+o);if(r){let t=l(b,1);for(let e=0;p>e;e++)m.push(c+u.slice(0,e)+t+u.slice(e)+o)}return"(?:"+t+"|"+m.join("|")+")"}));else{let t=l(b,f);2==a&&f>0&&(t=")("+t+")("),c=o.map(((e,n)=>1==h?.[n]?e:e.split("").map(((t,e,n)=>(1==f&&0==e&&n.length>1&&t[e]!=t[e+1]&&(t+="(?!"+t+")"),t))).join(t)))}let u=2==e?r:"",p=2==i?r:"",m=p+l(t.interChars,t.interIns)+u;return a>0?g?c=u+"("+c.join(")"+p+"|"+u+"(")+")"+p:(c="("+c.join(")("+m+")(")+")",c="(.?"+u+")"+c+"("+p+".*)"):(c=c.join(m),c=u+c+p),[RegExp(c,"i"),o]},z=(t,e,n)=>{let l=[],[r]=L(e);if(null!=n)for(let e=0;n.length>e;e++){let i=n[e];r.test(t[i])&&l.push(i)}else for(let e=0;t.length>e;e++)r.test(t[e])&&l.push(e);return l};let y=!!m,C=RegExp(p),E=RegExp(m);const k=(n,l,r)=>{let[s,a]=L(r,1),[h]=L(r,2),f=a.length,g=n.length,c=Array(g).fill(0),o={idx:Array(g),start:c.slice(),chars:c.slice(),terms:c.slice(),interIns:c.slice(),intraIns:c.slice(),interLft2:c.slice(),interRgt2:c.slice(),interLft1:c.slice(),interRgt1:c.slice(),ranges:Array(g)},u=1==e||1==i,p=0;for(let g=0;n.length>g;g++){let c=l[n[g]],m=c.match(s),b=m.index+m[1].length,S=b,d=!1,I=0,R=0,x=0,A=0,z=0,k=0,j=0,w=0,M=null;for(let n=0,l=2;f>n;n++,l+=2){let r=m[l].toLowerCase(),s=a[n],h=s.length,g=r.length,o=r==s;if(!o&&g>=h&&m[l+1].length>=h){let t=m[l+1].toLowerCase().indexOf(s);if(t>-1){let e=m[l]+m[l+1].slice(0,t);m[l-1]+=e,S+=e.length,0==n&&(b=S),m[l]=m[l+1].slice(t,t+h),m[l+1]=m[l+1].slice(t+h),r=m[l].toLowerCase(),g=h,o=!0,null==M&&(M=Array(f).fill(0)),M[n]=1}}if(u||o){let t=S-1,n=S+g,l=!0,r=!0;if(-1==t||C.test(c[t]))o&&I++;else{if(2==e){d=!0;break}if(y&&E.test(c[t]+c[t+1]))o&&R++;else{if(1==e){d=!0;break}l=!1}}if(n==c.length||C.test(c[n]))o&&x++;else{if(2==i){d=!0;break}if(y&&E.test(c[n-1]+c[n]))o&&A++;else{if(1==i){d=!0;break}r=!1}}o&&(z+=h,l&&r&&k++)}if(g>h&&(w+=g-h),n>0&&(j+=m[l-1].length),!t.intraFilt(s,r,S)){d=!0;break}f-1>n&&(S+=g+m[l+1].length)}if(!d){let t=null!=M?L(r,2,M)[0]:h;o.idx[p]=n[g],o.interLft2[p]=I,o.interLft1[p]=R,o.interRgt2[p]=x,o.interRgt1[p]=A,o.chars[p]=z,o.terms[p]=k,o.interIns[p]=j,o.intraIns[p]=w,o.start[p]=b;let e=c.match(t),l=o.ranges[p]=[],i=e.index+e[1].length,s=i,a=i;for(let t=2;e.length>t;t++){let n=e[t].length;i+=n,t%2==0?a=i:n>0&&(l.push(s,a),s=a=i)}a>s&&l.push(s,a),p++}}if(n.length>p)for(let t in o)o[t]=o[t].slice(0,p);return o};return{search:(...e)=>((e,n,l=!1,r=1e3,i)=>{let s=null,h=null;if(l){let t=A(n);if(t.length>1){let n=t.slice().sort(((t,e)=>e.length-t.length));for(let t=0;n.length>t;t++){if(0==i?.length)return[[],null,null];i=z(e,n[t],i)}s=a(t).map((t=>t.join(" "))),h=[];let l=new Set;for(let t=0;s.length>t;t++)if(i.length>l.size){let n=i.filter((t=>!l.has(t))),r=z(e,s[t],n);for(let t=0;r.length>t;t++)l.add(r[t]);h.push(r)}else h.push([])}}null==s&&(s=[n],h=[i?.length>0?i:z(e,n)]);let f=null,g=null;if(r>=h.reduce(((t,e)=>t+e.length),0)){f={},g=[];for(let n=0;h.length>n;n++){let l=h[n];if(null==l||0==l.length)continue;let r=s[n],i=k(l,e,r),a=t.sort(i,e,r);if(n>0)for(let t=0;a.length>t;t++)a[t]+=g.length;for(let t in i)f[t]=(f[t]??[]).concat(i[t]);g=g.concat(a)}}return[[].concat(...h),f,g]})(...e),split:A,filter:z,info:k,sort:t.sort}}const s=(()=>{let t={A:"ÁÀÃÂÄĄ",a:"áàãâäą",E:"ÉÈÊËĖ",e:"éèêëę",I:"ÍÌÎÏĮ",i:"íìîïį",O:"ÓÒÔÕÖ",o:"óòôõö",U:"ÚÙÛÜŪŲ",u:"úùûüūų",C:"ÇČ",c:"çč",N:"Ñ",n:"ñ",S:"Š",s:"š"},e=new Map,n="";for(let l in t)t[l].split("").forEach((t=>{n+=t,e.set(t,l)}));let l=RegExp(`[${n}]`,"g");return t=>{let n=Array(t.length);for(let r=0;t.length>r;r++)n[r]=t[r].replace(l,(t=>e.get(t)));return n}})();function a(t){let e,n,l=(t=t.slice()).length,r=[t.slice()],i=Array(l).fill(0),s=1;for(;l>s;)s>i[s]?(e=s%2&&i[s],n=t[s],t[s]=t[e],t[e]=n,++i[s],s=1,r.push(t.slice())):(i[s]=0,++s);return r}const h=(t,e)=>e?`<mark>${t}</mark>`:t,f=(t,e)=>t+e;return i.latinize=s,i.permute=t=>a([...Array(t.length).keys()]).sort(((t,e)=>{for(let n=0;t.length>n;n++)if(t[n]!=e[n])return t[n]-e[n];return 0})).map((e=>e.map((e=>t[e])))),i.highlight=function(t,e,n=h,l="",r=f){l=r(l,n(t.substring(0,e[0]),!1))??l;for(let i=0;e.length>i;i+=2)l=r(l,n(t.substring(e[i],e[i+1]),!0))??l,e.length-3>i&&(l=r(l,n(t.substring(e[i+1],e[i+2]),!1))??l);return r(l,n(t.substring(e[e.length-1]),!1))??l},i}();
{
"name": "@leeoniya/ufuzzy",
"version": "1.0.0",
"version": "1.0.1",
"description": "A tiny, efficient fuzzy matcher that doesn't suck",

@@ -41,5 +41,5 @@ "main": "./dist/uFuzzy.cjs.js",

"devDependencies": {
"@rollup/plugin-terser": "^0.3.0",
"rollup": "^3.10.1"
"@rollup/plugin-terser": "^0.4.0",
"rollup": "^3.11.0"
}
}

@@ -24,3 +24,3 @@ ## ▒ μFuzzy

- **Concise set of options** that don't interact in mysterious ways to drastically alter combined behavior.
- **Fast with low resource usage** - there's no index to build, so startup is below 1ms with near-zero memory overhead. Searching a three-term phrase in a 162,000 phrase dataset takes 12ms with in-order terms or 50ms with out-of-order terms.
- **Fast with low resource usage** - there's no index to build, so startup is below 1ms with near-zero memory overhead. Searching a three-term phrase in a 162,000 phrase dataset takes 13ms with out-of-order terms.
- **Micro, with zero dependencies** - currently [~5.5KB min](https://github.com/leeoniya/uFuzzy/blob/main/dist/uFuzzy.iife.min.js)

@@ -483,3 +483,3 @@

</td>
<td>★ 1.9k</td>
<td>★ 2k</td>
<td>5.5KB</td>

@@ -486,0 +486,0 @@ <td>0.3ms</td>

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc