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

minisearch

Package Overview
Dependencies
Maintainers
1
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

minisearch - npm Package Compare versions

Comparing version 0.1.4 to 0.1.5

2

dist/minisearch.js

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

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("minisearch",[],e):"object"==typeof exports?exports.minisearch=e():t.minisearch=e()}("undefined"!=typeof self?self:this,function(){return function(t){var e={};function n(i){if(e[i])return e[i].exports;var s=e[i]={i:i,l:!1,exports:{}};return t[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)n.d(i,s,function(e){return t[e]}.bind(null,s));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";n.r(e);class i{constructor(t,e=s){const n=t._tree,i=Object.keys(n);this.set=t,this.type=e,this.path=i.length>0?[{node:n,keys:i}]:[]}next(){const t=this.dive();return this.backtrack(),t}dive(){if(0===this.path.length)return{done:!0};const{node:t,keys:e}=u(this.path);return u(e)===c?{done:!1,value:this.result()}:(this.path.push({node:t[u(e)],keys:Object.keys(t[u(e)])}),this.dive())}backtrack(){0!==this.path.length&&(u(this.path).keys.pop(),u(this.path).keys.length>0||(this.path.pop(),this.backtrack()))}key(){return this.set._prefix+this.path.map(({keys:t})=>u(t)).filter(t=>t!==c).join("")}value(){return u(this.path).node[c]}result(){return this.type===o?this.value():this.type===r?this.key():[this.key(),this.value()]}[Symbol.iterator](){return this}}const s="ENTRIES",r="KEYS",o="VALUES",c="",u=function(t){return t[t.length-1]},h=function(t,e,n,i=0,s=d){const r=[{distance:0,ia:i,ib:0,edit:s}],o=[],c=[];for(;r.length>0;){const{distance:i,ia:s,ib:u,edit:h}=r.pop();if(o[s]=o[s]||[],!(o[s][u]&&o[s][u]<=i))if(o[s][u]=i,u!==e.length)if(t[s]===e[u])r.push({distance:i,ia:s+1,ib:u+1,edit:d});else{if(i>=n)continue;h!==l&&r.push({distance:i+1,ia:s,ib:u+1,edit:a}),s<t.length&&(h!==a&&r.push({distance:i+1,ia:s+1,ib:u,edit:l}),h!==a&&h!==l&&r.push({distance:i+1,ia:s+1,ib:u+1,edit:f}))}else c.push({distance:i,i:s,edit:h})}return c},d=0,f=1,l=2,a=3;var p=function(t,e,n){const i=[{distance:0,i:0,key:"",node:t}],s={};for(;i.length>0;){const{node:t,distance:r,key:o,i:u,edit:d}=i.pop();Object.keys(t).forEach(f=>{if(f===c){const i=r+(e.length-u),[,c]=s[o]||[null,1/0];i<=n&&i<c&&(s[o]=[t[f],i])}else h(e,f,n-r,u,d).forEach(({distance:e,i:n,edit:s})=>{i.push({node:t[f],distance:r+e,key:o+f,i:n,edit:s})})})}return s};class m{constructor(t={},e=""){this._tree=t,this._prefix=e}atPrefix(t){if(!t.startsWith(this._prefix))throw new Error("Mismatched prefix");const[e,n]=_(this._tree,t.slice(this._prefix.length));if(void 0===e){const[e,i]=x(n),s=Object.keys(e).find(t=>t!==c&&t.startsWith(i));if(void 0!==s)return new m({[s.slice(i.length)]:e[s]},t)}return new m(e||{},t)}clear(){delete this._size,this._tree={}}delete(t){return delete this._size,O(this._tree,t)}entries(){return new i(this,s)}forEach(t){for(let[e,n]of this)t(e,n,this)}fuzzyGet(t,e){return p(this._tree,t,e)}get(t){const e=y(this._tree,t);return void 0!==e?e[c]:void 0}has(t){const e=y(this._tree,t);return void 0!==e&&e.hasOwnProperty(c)}keys(){return new i(this,r)}set(t,e){if("string"!=typeof t)throw new Error("key must be a string");return delete this._size,b(this._tree,t)[c]=e,this}get size(){return this._size?this._size:(this._size=0,this.forEach(()=>{this._size+=1}),this._size)}update(t,e){if("string"!=typeof t)throw new Error("key must be a string");delete this._size;const n=b(this._tree,t);return n[c]=e(n[c]),this}values(){return new i(this,o)}[Symbol.iterator](){return this.entries()}}m.from=function(t){const e=new m;for(let[n,i]of t)e.set(n,i);return e},m.fromObject=function(t){return m.from(Object.entries(t))};const _=function(t,e,n=[]){if(0===e.length)return[t,n];const i=Object.keys(t).find(t=>t!==c&&e.startsWith(t));return void 0===i?_(void 0,"",[...n,[t,e]]):_(t[i],e.slice(i.length),[...n,[t,i]])},y=function(t,e){if(0===e.length)return t;const n=Object.keys(t).find(t=>t!==c&&e.startsWith(t));return void 0!==n?y(t[n],e.slice(n.length)):void 0},b=function(t,e){if(0===e.length)return t;const n=Object.keys(t).find(t=>t!==c&&e.startsWith(t));if(void 0===n){const n=Object.keys(t).find(t=>t!==c&&t.startsWith(e[0]));if(void 0!==n){const i=g(e,n);return t[i]={[n.slice(i.length)]:t[n]},delete t[n],b(t[i],e.slice(i.length))}return t[e]={},t[e]}return b(t[n],e.slice(n.length))},g=function(t,e,n=0,i=Math.min(t.length,e.length),s=""){return n>=i?s:t[n]!==e[n]?s:g(t,e,n+1,i,s+t[n])},O=function(t,e){const[n,i]=_(t,e);if(void 0===n)return;delete n[c];const s=Object.keys(n);0===s.length&&k(i),1===s.length&&v(i,s[0],n[s[0]])},k=function(t){if(0===t.length)return;const[e,n]=x(t);delete e[n],0===Object.keys(e).length&&k(t.slice(0,-1))},v=function(t,e,n){if(0===t.length)return;const[i,s]=x(t);i[s+e]=n,delete i[s]},x=function(t){return t[t.length-1]};var j=m;const z="or";class w{constructor(t={}){this._options={...P,...t},this._options.searchOptions={...T,...this._options.searchOptions||{}};const{fields:e}=this._options;if(null==e)throw new Error('Option "fields" must be provided');this._index=new j,this._documentCount=0,this._documentIds={},this._fieldIds={},I(this,e)}add(t){const{tokenize:e,processTerm:n,fields:i,idField:s}=this._options;if(null==t[s])throw new Error(`Document does not have ID field "${s}"`);const r=S(this,t[s]);i.filter(e=>null!=t[e]).forEach(i=>{e(t[i]).forEach(t=>{E(this,this._fieldIds[i],r,n(t))})})}addAll(t){t.forEach(t=>this.add(t))}search(t,e={}){const{tokenize:n,processTerm:i,searchOptions:s}=this._options;e={...s,...e};const r=n(t).map(i).map(e.termToQuery).map(t=>this.executeQuery(t,e)),o=this.combineResults(r,e.combineWith);return Object.entries(o).map(([t,{score:e,match:n}])=>({id:this._documentIds[t],score:e,match:n})).sort(({score:t},{score:e})=>t<e?1:-1)}get documentCount(){return this._documentCount}executeQuery(t,e={}){const n=((e={...this._options.defaultSearchOptions,...e}).fields||this._options.fields).reduce((t,e)=>({...t,[e]:t[e]||1}),e.boost||{});if(!t.fuzzy&&!t.prefix)return C(this,t.term,n,this._index.get(t.term));const i=[];if(t.fuzzy){const e=t.fuzzy<1?Math.round(t.term.length*t.fuzzy):t.fuzzy;Object.entries(this._index.fuzzyGet(t.term,e)).forEach(([t,[e,s]])=>{i.push(C(this,t,n,e,s))})}return t.prefix&&this._index.atPrefix(t.term).forEach((e,s)=>{i.push(C(this,e,n,s,e.length-t.term.length))}),i.reduce(M[z],{})}combineResults(t,e=z){if(0===t.length)return{};const n=e.toLowerCase();return t.reduce(M[n],null)}toJSON(){return{index:this._index,documentCount:this._documentCount,documentIds:this._documentIds,fieldIds:this._fieldIds}}toJS(){this.toJSON()}}w.loadJSON=function(t,e={}){return w.loadJS(JSON.parse(t),e)},w.loadJS=function(t,e={}){const{index:{_tree:n,_prefix:i},documentCount:s,documentIds:r,fieldIds:o}=t,c=new w(e);return c._index=new j(n,i),c._documentCount=s,c._documentIds=r,c._fieldIds=o,c},w.SearchableMap=j;const E=function(t,e,n,i){t._index.update(i,t=>{const i=(t=t||{})[e]||{df:0,ds:{}};return null==i.ds[n]&&(i.df+=1),i.ds[n]=(i.ds[n]||0)+1,{...t,[e]:i}})},S=function(t,e){const n=t._documentCount;return t._documentIds[n]=e,t._documentCount+=1,n},I=function(t,e){e.forEach((e,n)=>{t._fieldIds[e]=n})},C=function(t,e,n,i,s=0){return null==i?{}:Object.entries(n).reduce((n,[r,o])=>{const{df:c,ds:u}=i[t._fieldIds[r]]||{ds:{}};return Object.entries(u).forEach(([i,u])=>{const h=o/(1+.333*o*s);n[i]=n[i]||{score:0,match:{}},n[i].match[e]=n[i].match[e]||[],n[i].score=n[i].score+h*W(u,c,t._documentCount),n[i].match[e].push(r)}),n},{})},M={[z]:function(t,e){return Object.entries(e).reduce((t,[e,{match:n,score:i}])=>(t[e]=t[e]||{score:0,match:{}},t[e].score=t[e].score+i,t[e].match={...t[e].match,...n},t),t||{})},and:function(t,e){return null==t?e:Object.entries(e).reduce((e,[n,{score:i,match:s}])=>void 0===t[n]?e:(e[n]=e[n]||{},e[n].score=Math.min(t[n].score,i),e[n].match={...t[n].match,...s},e),{})}},W=function(t,e,n){return t*Math.log(n/e)},P={idField:"id",tokenize:t=>t.split(/\W+/).filter(t=>t.length>1),processTerm:t=>t.toLowerCase()},T={termToQuery:t=>({term:t}),combineWith:z};var J=w;e.default=J}]).default});
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("minisearch",[],t):"object"==typeof exports?exports.minisearch=t():e.minisearch=t()}("undefined"!=typeof self?self:this,function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var s=t[i]={i:i,l:!1,exports:{}};return e[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)n.d(i,s,function(t){return e[t]}.bind(null,s));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);class i{constructor(e,t=s){const n=e._tree,i=Object.keys(n);this.set=e,this.type=t,this.path=i.length>0?[{node:n,keys:i}]:[]}next(){const e=this.dive();return this.backtrack(),e}dive(){if(0===this.path.length)return{done:!0};const{node:e,keys:t}=u(this.path);return u(t)===c?{done:!1,value:this.result()}:(this.path.push({node:e[u(t)],keys:Object.keys(e[u(t)])}),this.dive())}backtrack(){0!==this.path.length&&(u(this.path).keys.pop(),u(this.path).keys.length>0||(this.path.pop(),this.backtrack()))}key(){return this.set._prefix+this.path.map(({keys:e})=>u(e)).filter(e=>e!==c).join("")}value(){return u(this.path).node[c]}result(){return this.type===o?this.value():this.type===r?this.key():[this.key(),this.value()]}[Symbol.iterator](){return this}}const s="ENTRIES",r="KEYS",o="VALUES",c="",u=function(e){return e[e.length-1]},d=function(e,t,n,i=0,s=h){const r=[{distance:0,ia:i,ib:0,edit:s}],o=[],c=[];for(;r.length>0;){const{distance:i,ia:s,ib:u,edit:d}=r.pop();if(o[s]=o[s]||[],!(o[s][u]&&o[s][u]<=i))if(o[s][u]=i,u!==t.length)if(e[s]===t[u])r.push({distance:i,ia:s+1,ib:u+1,edit:h});else{if(i>=n)continue;d!==f&&r.push({distance:i+1,ia:s,ib:u+1,edit:a}),s<e.length&&(d!==a&&r.push({distance:i+1,ia:s+1,ib:u,edit:f}),d!==a&&d!==f&&r.push({distance:i+1,ia:s+1,ib:u+1,edit:l}))}else c.push({distance:i,i:s,edit:d})}return c},h=0,l=1,f=2,a=3;var p=function(e,t,n){const i=[{distance:0,i:0,key:"",node:e}],s={};for(;i.length>0;){const{node:e,distance:r,key:o,i:u,edit:h}=i.pop();Object.keys(e).forEach(l=>{if(l===c){const i=r+(t.length-u),[,c]=s[o]||[null,1/0];i<=n&&i<c&&(s[o]=[e[l],i])}else d(t,l,n-r,u,h).forEach(({distance:t,i:n,edit:s})=>{i.push({node:e[l],distance:r+t,key:o+l,i:n,edit:s})})})}return s};class m{constructor(e={},t=""){this._tree=e,this._prefix=t}atPrefix(e){if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");const[t,n]=_(this._tree,e.slice(this._prefix.length));if(void 0===t){const[t,i]=k(n),s=Object.keys(t).find(e=>e!==c&&e.startsWith(i));if(void 0!==s)return new m({[s.slice(i.length)]:t[s]},e)}return new m(t||{},e)}clear(){delete this._size,this._tree={}}delete(e){return delete this._size,v(this._tree,e)}entries(){return new i(this,s)}forEach(e){for(let[t,n]of this)e(t,n,this)}fuzzyGet(e,t){return p(this._tree,e,t)}get(e){const t=y(this._tree,e);return void 0!==t?t[c]:void 0}has(e){const t=y(this._tree,e);return void 0!==t&&t.hasOwnProperty(c)}keys(){return new i(this,r)}set(e,t){if("string"!=typeof e)throw new Error("key must be a string");return delete this._size,b(this._tree,e)[c]=t,this}get size(){return this._size?this._size:(this._size=0,this.forEach(()=>{this._size+=1}),this._size)}update(e,t){if("string"!=typeof e)throw new Error("key must be a string");delete this._size;const n=b(this._tree,e);return n[c]=t(n[c]),this}values(){return new i(this,o)}[Symbol.iterator](){return this.entries()}}m.from=function(e){const t=new m;for(let[n,i]of e)t.set(n,i);return t},m.fromObject=function(e){return m.from(Object.entries(e))};const _=function(e,t,n=[]){if(0===t.length)return[e,n];const i=Object.keys(e).find(e=>e!==c&&t.startsWith(e));return void 0===i?_(void 0,"",[...n,[e,t]]):_(e[i],t.slice(i.length),[...n,[e,i]])},y=function(e,t){if(0===t.length)return e;const n=Object.keys(e).find(e=>e!==c&&t.startsWith(e));return void 0!==n?y(e[n],t.slice(n.length)):void 0},b=function(e,t){if(0===t.length)return e;const n=Object.keys(e).find(e=>e!==c&&t.startsWith(e));if(void 0===n){const n=Object.keys(e).find(e=>e!==c&&e.startsWith(t[0]));if(void 0!==n){const i=g(t,n);return e[i]={[n.slice(i.length)]:e[n]},delete e[n],b(e[i],t.slice(i.length))}return e[t]={},e[t]}return b(e[n],t.slice(n.length))},g=function(e,t,n=0,i=Math.min(e.length,t.length),s=""){return n>=i?s:e[n]!==t[n]?s:g(e,t,n+1,i,s+e[n])},v=function(e,t){const[n,i]=_(e,t);if(void 0===n)return;delete n[c];const s=Object.keys(n);0===s.length&&O(i),1===s.length&&x(i,s[0],n[s[0]])},O=function(e){if(0===e.length)return;const[t,n]=k(e);delete t[n],0===Object.keys(t).length&&O(e.slice(0,-1))},x=function(e,t,n){if(0===e.length)return;const[i,s]=k(e);i[s+t]=n,delete i[s]},k=function(e){return e[e.length-1]};var j=m;const w="or";class z{constructor(e={}){this._options={...J,...e},this._options.searchOptions={...D,...this._options.searchOptions||{}};const{fields:t}=this._options;if(null==t)throw new Error('Option "fields" must be provided');this._index=new j,this._documentCount=0,this._documentIds={},this._fieldIds={},M(this,t)}add(e){const{tokenize:t,processTerm:n,fields:i,idField:s}=this._options;if(null==e[s])throw new Error(`Document does not have ID field "${s}"`);const r=C(this,e[s]);i.filter(t=>null!=e[t]).forEach(i=>{t(e[i]).forEach(e=>{E(this,this._fieldIds[i],r,n(e))})})}addAll(e){e.forEach(e=>this.add(e))}remove(e){const{tokenize:t,processTerm:n,fields:i,idField:s}=this._options;if(null==e[s])throw new Error(`Document does not have ID field "${s}"`);const[r]=Object.entries(this._documentIds).find(([t,n])=>e[s]===n)||[];if(null==r)throw new Error(`Cannot remove document with ID ${e[s]}: it is not in the index`);i.filter(t=>null!=e[t]).forEach(i=>{t(e[i]).forEach(e=>{I(this,this._fieldIds[i],r,n(e))})}),this._documentCount-=1}search(e,t={}){const{tokenize:n,processTerm:i,searchOptions:s}=this._options;t={...s,...t};const r=n(e).map(i).map(t.termToQuery).map(e=>this.executeQuery(e,t)),o=this.combineResults(r,t.combineWith);return Object.entries(o).map(([e,{score:t,match:n}])=>({id:this._documentIds[e],score:t,match:n})).sort(({score:e},{score:t})=>e<t?1:-1)}get documentCount(){return this._documentCount}executeQuery(e,t={}){const n=((t={...this._options.defaultSearchOptions,...t}).fields||this._options.fields).reduce((e,t)=>({...e,[t]:e[t]||1}),t.boost||{});if(!e.fuzzy&&!e.prefix)return T(this,e.term,n,this._index.get(e.term));const i=[];if(e.fuzzy){const t=e.fuzzy<1?Math.round(e.term.length*e.fuzzy):e.fuzzy;Object.entries(this._index.fuzzyGet(e.term,t)).forEach(([e,[t,s]])=>{i.push(T(this,e,n,t,s))})}return e.prefix&&this._index.atPrefix(e.term).forEach((t,s)=>{i.push(T(this,t,n,s,t.length-e.term.length))}),i.reduce(W[w],{})}combineResults(e,t=w){if(0===e.length)return{};const n=t.toLowerCase();return e.reduce(W[n],null)}toJSON(){return{index:this._index,documentCount:this._documentCount,documentIds:this._documentIds,fieldIds:this._fieldIds}}toJS(){this.toJSON()}}z.loadJSON=function(e,t={}){return z.loadJS(JSON.parse(e),t)},z.loadJS=function(e,t={}){const{index:{_tree:n,_prefix:i},documentCount:s,documentIds:r,fieldIds:o}=e,c=new z(t);return c._index=new j(n,i),c._documentCount=s,c._documentIds=r,c._fieldIds=o,c},z.SearchableMap=j;const E=function(e,t,n,i){e._index.update(i,e=>{const i=(e=e||{})[t]||{df:0,ds:{}};return null==i.ds[n]&&(i.df+=1),i.ds[n]=(i.ds[n]||0)+1,{...e,[t]:i}})},I=function(e,t,n,i){e._index.has(i)?(e._index.update(i,s=>{const r=s[t];return null==r||null==r.ds[n]?(S(e,n,t,i),s):r.df<=1?(delete s[t],s):(r.df-=1,r.ds[n]<=1?(delete r.ds[n],s):(r.ds[n]-=1,{...s,[t]:r}))}),0===Object.keys(e._index.get(i)).length&&e._index.delete(i)):S(e,n,t,i)},S=function(e,t,n,i){if(null==console||null==console.warn)return;const s=Object.entries(e._fieldIds).find(([e,t])=>t===n)[0];console.warn(`MiniSearch: document with ID ${e._documentIds[t]} has changed before removal: term "${i}" was not present in field "${s}". Removing a document after it has changed can corrupt the index!`)},C=function(e,t){const n=e._documentCount;return e._documentIds[n]=t,e._documentCount+=1,n},M=function(e,t){t.forEach((t,n)=>{e._fieldIds[t]=n})},T=function(e,t,n,i,s=0){return null==i?{}:Object.entries(n).reduce((n,[r,o])=>{const{df:c,ds:u}=i[e._fieldIds[r]]||{ds:{}};return Object.entries(u).forEach(([i,u])=>{const d=o/(1+.333*o*s);n[i]=n[i]||{score:0,match:{}},n[i].match[t]=n[i].match[t]||[],n[i].score=n[i].score+d*P(u,c,e._documentCount),n[i].match[t].push(r)}),n},{})},W={[w]:function(e,t){return Object.entries(t).reduce((e,[t,{match:n,score:i}])=>(e[t]=e[t]||{score:0,match:{}},e[t].score=e[t].score+i,e[t].match={...e[t].match,...n},e),e||{})},and:function(e,t){return null==e?t:Object.entries(t).reduce((t,[n,{score:i,match:s}])=>void 0===e[n]?t:(t[n]=t[n]||{},t[n].score=Math.min(e[n].score,i),t[n].match={...e[n].match,...s},t),{})}},P=function(e,t,n){return e*Math.log(n/t)},J={idField:"id",tokenize:e=>e.split(/\W+/).filter(e=>e.length>1),processTerm:e=>e.toLowerCase()},D={termToQuery:e=>({term:e}),combineWith:w};var $=z;t.default=$}]).default});

@@ -327,2 +327,8 @@ window.esdocSearchIndex = [

[
"src/minisearch.js~minisearch#remove",
"class/src/MiniSearch.js~MiniSearch.html#instance-method-remove",
"src/MiniSearch.js~MiniSearch#remove",
"method"
],
[
"src/minisearch.js~minisearch#search",

@@ -329,0 +335,0 @@ "class/src/MiniSearch.js~MiniSearch.html#instance-method-search",

{
"name": "minisearch",
"version": "0.1.4",
"version": "0.1.5",
"description": "fun with fulltext search",

@@ -5,0 +5,0 @@ "main": "dist/minisearch.js",

@@ -70,3 +70,3 @@ # MiniSearch

let results = miniSearch.search('zen art motorcycle')
// => [ { id: 2, score: 2.77258, match: { ... } }, { id: 4, score: 1.38629, { ... } } ]
// => [ { id: 2, score: 2.77258, match: { ... } }, { id: 4, score: 1.38629, match: { ... } } ]

@@ -73,0 +73,0 @@ // Search only specific fields

@@ -99,2 +99,3 @@ import SearchableMap from './SearchableMap/SearchableMap.js'

* Adds a document to the index
*
* @param {Object} document - the document to be indexed

@@ -117,2 +118,3 @@ */

* Adds all the given documents to the index
*
* @param {Object[]} documents - an array of documents to be indexed

@@ -125,2 +127,33 @@ */

/**
* Removes the given document from the index.
*
* The document to delete must NOT have changed between indexing and deletion,
* otherwise the index will be corrupted. Therefore, when reindexing a document
* after a change, the correct order of operations is:
*
* 1. remove old version
* 2. apply changes
* 3. index new version
*
* @param {Object} document - the document to be indexed
*/
remove (document) {
const { tokenize, processTerm, fields, idField } = this._options
if (document[idField] == null) {
throw new Error(`Document does not have ID field "${idField}"`)
}
const [shortDocumentId] = Object.entries(this._documentIds)
.find(([_, longId]) => document[idField] === longId) || []
if (shortDocumentId == null) {
throw new Error(`Cannot remove document with ID ${document[idField]}: it is not in the index`)
}
fields.filter(field => document[field] != null).forEach(field => {
tokenize(document[field]).forEach(term => {
removeTerm(this, this._fieldIds[field], shortDocumentId, processTerm(term))
})
})
this._documentCount -= 1
}
/**
* Search for documents matching the given search query.

@@ -240,2 +273,3 @@ *

* with MiniSearch.fromJSON
*
* @return {string} the JSON-serialized index

@@ -265,2 +299,3 @@ */

* originally used when serializing the index.
*
* @param {string} json - JSON-serialized index

@@ -299,2 +334,36 @@ * @param {Object} options - configuration options, same as the constructor

const removeTerm = function (self, fieldId, documentId, term) {
if (!self._index.has(term)) {
warnDocumentChanged(self, documentId, fieldId, term)
return
}
self._index.update(term, indexData => {
const fieldIndex = indexData[fieldId]
if (fieldIndex == null || fieldIndex.ds[documentId] == null) {
warnDocumentChanged(self, documentId, fieldId, term)
return indexData
}
if (fieldIndex.df <= 1) {
delete indexData[fieldId]
return indexData
}
fieldIndex.df -= 1
if (fieldIndex.ds[documentId] <= 1) {
delete fieldIndex.ds[documentId]
return indexData
}
fieldIndex.ds[documentId] -= 1
return { ...indexData, [fieldId]: fieldIndex }
})
if (Object.keys(self._index.get(term)).length === 0) {
self._index.delete(term)
}
}
const warnDocumentChanged = function (self, shortDocumentId, fieldId, term) {
if (console == null || console.warn == null) { return }
const fieldName = Object.entries(self._fieldIds).find(([name, id]) => id === fieldId)[0]
console.warn(`MiniSearch: document with ID ${self._documentIds[shortDocumentId]} has changed before removal: term "${term}" was not present in field "${fieldName}". Removing a document after it has changed can corrupt the index!`)
}
const addDocumentId = function (self, documentId) {

@@ -301,0 +370,0 @@ const shortDocumentId = self._documentCount

@@ -35,2 +35,62 @@ /* eslint-env jest */

describe('remove', () => {
const documents = [
{ id: 1, title: 'Divina Commedia', text: 'Nel mezzo del cammin di nostra vita' },
{ id: 2, title: 'I Promessi Sposi', text: 'Quel ramo del lago di Como' },
{ id: 3, title: 'Vita Nova', text: 'In quella parte del libro della mia memoria' }
]
let ms
beforeEach(() => {
ms = new MiniSearch({ fields: ['title', 'text'] })
ms.addAll(documents)
})
it('removes the document from the index', () => {
expect(ms.documentCount).toEqual(3)
ms.remove(documents[0])
expect(ms.documentCount).toEqual(2)
expect(ms.search('commedia').length).toEqual(0)
expect(ms.search('vita').map(({ id }) => id)).toEqual([3])
})
it('cleans up the index', () => {
ms.remove(documents[0])
expect(ms._index.has('commedia')).toEqual(false)
expect(Object.keys(ms._index.get('vita'))).toEqual([ms._fieldIds.title.toString()])
})
describe('when the document was not in the index', () => {
it('throws an error', () => {
expect(() => ms.remove({ id: 99 }))
.toThrow('Cannot remove document with ID 99: it is not in the index')
})
})
describe('when the document has changed', () => {
let _warn
beforeEach(() => {
_warn = console.warn
console.warn = jest.fn()
})
afterEach(() => {
console.warn = _warn
})
it('warns of possible index corruption', () => {
expect(() => ms.remove({ id: 1, title: 'Divina Commedia cammin', text: 'something has changed' }))
.not.toThrow()
expect(console.warn).toHaveBeenCalledTimes(4)
;[
['cammin', 'title'],
['something', 'text'],
['has', 'text'],
['changed', 'text']
].forEach(([term, field], i) => {
expect(console.warn).toHaveBeenNthCalledWith(i + 1, `MiniSearch: document with ID 1 has changed before removal: term "${term}" was not present in field "${field}". Removing a document after it has changed can corrupt the index!`)
})
})
})
})
describe('addAll', () => {

@@ -124,7 +184,16 @@ it('adds all the documents to the index', () => {

it('works the same with all combinators', () => {
const resultsOr = ms.search('vita nova', { combineWith: 'OR' })
const resultsAnd = ms.search('vita nova', { combineWith: 'AND' })
expect(resultsOr[0].match).toEqual(resultsAnd[0].match)
it('reports correct info when combining terms with AND', () => {
const results = ms.search('vita nova', { combineWith: 'AND' })
expect(results.map(({ match }) => match)).toEqual([
{ vita: ['title', 'text'], nova: ['title'] }
])
})
it('reports correct info for fuzzy and prefix queries', () => {
const results = ms.search('vi nuova', { termToQuery: term => ({ term, fuzzy: 0.2, prefix: true }) })
expect(results.map(({ match }) => match)).toEqual([
{ vita: ['title', 'text'], nova: ['title'] },
{ vita: ['text'] }
])
})
})

@@ -131,0 +200,0 @@ })

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

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