diff --git a/dist/haro.cjs.js b/dist/haro.cjs.js index 4f550e7..f8db87a 100644 --- a/dist/haro.cjs.js +++ b/dist/haro.cjs.js @@ -69,28 +69,35 @@ function s () { return ((Math.random() + 1) * 0x10000 | 0).toString(16).substring(1); } -function setIndex (index, indexes, delimiter, key, data, indice, pattern) { +function setIndex (index, indexes, delimiter, key, data, indice) { each(!indice ? index : [indice], i => { const lindex = indexes.get(i); - if (Array.isArray(data[i]) && !i.includes(delimiter)) { - each(data[i], d => { - if (!lindex.has(d)) { - lindex.set(d, new Set()); + if (i.includes(delimiter)) { + const keys = i.split(delimiter), + results = keys.reduce((a, li, lidx) => { + const result = []; + + (Array.isArray(data[li]) ? data[li] : [data[li]]).forEach(lli => lidx === 0 ? result.push(lli) : a.forEach(x => result.push(`${x}|${lli}`))); + + return result; + }, []); + + each(results, c => { + if (!lindex.has(c)) { + lindex.set(c, new Set()); } - lindex.get(d).add(key); + lindex.get(c).add(key); }); } else { - const lidx = keyIndex(i, data, delimiter, pattern); - - if (lidx !== void 0 && lidx !== null) { - if (!lindex.has(lidx)) { - lindex.set(lidx, new Set()); + each(Array.isArray(data[i]) ? data[i] : [data[i]], d => { + if (!lindex.has(d)) { + lindex.set(d, new Set()); } - lindex.get(lidx).add(key); - } + lindex.get(d).add(key); + }); } }); } diff --git a/dist/haro.esm.js b/dist/haro.esm.js index ce85708..78a8c8e 100644 --- a/dist/haro.esm.js +++ b/dist/haro.esm.js @@ -1 +1 @@ -const e=[8,9,"a","b"];function t(e){return JSON.parse(JSON.stringify(e,null,0))}function s(e,t){for(const s of e.entries())t(s[1],s[0]);return e}function r(e,t,s,r){let i;return i=e.includes(s)?e.split(s).sort(((e,t)=>e.localeCompare(t))).map((e=>(void 0!==t[e]?t[e]:"").toString().replace(new RegExp(r,"g"),"").toLowerCase())).join(s):t[e],i}function i(e,t,s,i,n,a){e.forEach((e=>{const h=t.get(e),o=r(e,n,s,a);if(h.has(o)){const e=h.get(o);e.delete(i),0===e.size&&h.delete(o)}}))}function n(e,t){return e instanceof Object&&t instanceof Object?s(Object.keys(t),(s=>{e[s]instanceof Object&&t[s]instanceof Object?e[s]=n(e[s],t[s]):Array.isArray(e[s])&&Array.isArray(t[s])?e[s]=e[s].concat(t[s]):e[s]=t[s]})):e=Array.isArray(e)&&Array.isArray(t)?e.concat(t):t,e}function a(){return(65536*(Math.random()+1)|0).toString(16).substring(1)}function h(e,t,i,n,a,h,o){s(h?[h]:e,(e=>{const h=t.get(e);if(Array.isArray(a[e])&&!e.includes(i))s(a[e],(e=>{h.has(e)||h.set(e,new Set),h.get(e).add(n)}));else{const t=r(e,a,i,o);null!=t&&(h.has(t)||h.set(t,new Set),h.get(t).add(n))}}))}function o(){return a()+a()+"-"+a()+"-4"+a().substr(0,3)+"-"+e[Math.floor(4*Math.random())]+a().substr(0,3)+"-"+a()+a()+a()}class c{constructor({delimiter:e="|",id:t=o(),index:s=[],key:r="",pattern:i="\\s*|\\t*",versioning:n=!1}={}){return this.data=new Map,this.delimiter=e,this.id=t,this.index=s,this.indexes=new Map,this.key=r,this.pattern=i,this.size=0,this.versions=new Map,this.versioning=n,Object.defineProperty(this,"registry",{enumerable:!0,get:()=>Array.from(this.data.keys())}),this.reindex()}async batch(e,t="set",s=!1){let r;try{const i="del"===t?e=>this.del(e,!0,s):e=>this.set(null,e,!0,!0,s);r=await Promise.all(this.beforeBatch(e,t).map(i)),r=this.onbatch(r,t)}catch(e){throw this.onerror("batch",e),e}return r}beforeBatch(e){return e}beforeClear(){}beforeDelete(){}beforeSet(){}clear(){return this.beforeClear(),this.size=0,this.data.clear(),this.indexes.clear(),this.versions.clear(),this.reindex().onclear(),this}del(e,t=!1,s=!1,r=!1){if(!1===this.has(e))throw new Error("Record not found");const n=this.get(e,!0);return this.exec((async()=>{this.beforeDelete(e,t,s,r),i(this.index,this.indexes,this.delimiter,e,n,this.pattern),this.data.delete(e),--this.size}),(async()=>{this.ondelete(e,t,r,s),this.versioning&&this.versions.delete(e)}),(e=>{throw this.onerror("delete",e),e}))}dump(e="records"){let t;return t="records"===e?Array.from(this.entries()):Array.from(this.indexes).map((e=>(e[1]=Array.from(e[1]).map((e=>(e[1]=Array.from(e[1]),e))),e))),t}entries(){return this.data.entries()}async exec(e,t,s){let r;try{r=await t(await e())}catch(e){s(e)}return r}find(e,t=!1){const s=Object.keys(e).sort(((e,t)=>e.localeCompare(t))).join(this.delimiter),i=r(s,e,this.delimiter,this.pattern),n=Array.from((this.indexes.get(s)||new Map).get(i)||new Set).map((e=>this.get(e,t)));return t?n:this.list(...n)}filter(e,t=!1){const s=t?(e,t)=>t:(e,t)=>Object.freeze([e,Object.freeze(t)]),r=this.reduce(((t,r,i,n)=>(e.call(n,r)&&t.push(s(i,r)),t)),[]);return t?r:Object.freeze(r)}forEach(e,s){return this.data.forEach(((s,r)=>e(t(s),t(r))),s||this.data),this}get(e,s=!1){const r=t(this.data.get(e)||null);return s?r:this.list(e,r)}has(e,t=this.data){return t.has(e)}keys(){return this.data.keys()}limit(e=0,t=0,s=!1){const r=this.registry.slice(e,e+t).map((e=>this.get(e,s)));return s?r:this.list(...r)}list(...e){return Object.freeze(e.map((e=>Object.freeze(e))))}map(e,t=!1){const s=[];return this.forEach(((t,r)=>s.push(e(t,r)))),t?s:this.list(...s)}onbatch(e){return e}onclear(){}ondelete(){}onerror(){}onset(){}async override(e,t="records"){if("indexes"===t)this.indexes=new Map(e.map((e=>[e[0],new Map(e[1].map((e=>[e[0],new Set(e[1])])))])));else{if("records"!==t)throw new Error("Invalid type");this.indexes.clear(),this.data=new Map(e),this.size=this.data.size}return!0}reduce(e,t,s=!1){let r=t||this.data.keys().next().value;return this.forEach(((t,i)=>{r=e(r,t,i,this,s)}),this),r}reindex(e){const t=e?[e]:this.index;return e&&!1===this.index.includes(e)&&this.index.push(e),s(t,(e=>this.indexes.set(e,new Map))),this.forEach(((e,r)=>s(t,(t=>h(this.index,this.indexes,this.delimiter,r,e,t,this.pattern))))),this}search(e,t,r=!1){const i=new Map,n="function"==typeof e,a=e&&"function"==typeof e.test;return e&&s(t?Array.isArray(t)?t:[t]:this.index,(t=>{let s=this.indexes.get(t);s&&s.forEach(((s,h)=>{switch(!0){case n&&e(h,t):case a&&e.test(Array.isArray(h)?h.join(", "):h):case h===e:s.forEach((e=>{!i.has(e)&&this.has(e)&&i.set(e,this.get(e,r))}))}}))})),r?Array.from(i.values()):this.list(...Array.from(i.values()))}async set(e,s,r=!1,a=!1,c=!1,l=!1){let d,u=t(s);return this.exec((async()=>(null==e&&(e=this.key&&void 0!==u[this.key]?u[this.key]:o()),this.beforeSet(e,s,r,a,c,l),this.data.has(e)?(d=this.get(e,!0),i(this.index,this.indexes,this.delimiter,e,d,this.pattern),this.versioning&&this.versions.get(e).add(Object.freeze(t(d))),!1===a&&(u=n(t(d),u))):(++this.size,this.versioning&&this.versions.set(e,new Set)),this.data.set(e,u),h(this.index,this.indexes,this.delimiter,e,u,null,this.pattern),this.get(e))),(async e=>(this.onset(e,r,l,c),e)),(e=>{throw this.onerror("set",e),e}))}sort(e,t=!0){return t?Object.freeze(this.limit(0,this.size,!0).sort(e).map((e=>Object.freeze(e)))):this.limit(0,this.size,!0).sort(e)}sortBy(e,t=!1){const r=[],i=[];let n;return this.indexes.has(e)||this.reindex(e),n=this.indexes.get(e),n.forEach(((e,t)=>i.push(t))),s(i.sort(),(e=>n.get(e).forEach((e=>r.push(this.get(e,t)))))),t?r:this.list(...r)}toArray(e=!0){const r=Array.from(this.data.values()).map((e=>t(e)));return e&&(s(r,(e=>Object.freeze(e))),Object.freeze(r)),r}values(){return this.data.values()}where(e,t=!1,s="||"){const r=this.index.filter((t=>t in e));return r.length>0?this.filter(new Function("a",`return (${r.map((t=>{let r;if(Array.isArray(e[t]))r=`Array.isArray(a['${t}']) ? ${e[t].map((e=>`a['${t}'].includes(${"string"==typeof e?`'${e}'`:e})`)).join(` ${s} `)} : (${e[t].map((e=>`a['${t}'] === ${"string"==typeof e?`'${e}'`:e}`)).join(` ${s} `)})`;else if(e[t]instanceof RegExp)r=`Array.isArray(a['${t}']) ? a['${t}'].filter(i => ${e[t]}.test(a['${t}'])).length > 0 : ${e[t]}.test(a['${t}'])`;else{const s="string"==typeof e[t]?`'${e[t]}'`:e[t];r=`Array.isArray(a['${t}']) ? a['${t}'].includes(${s}) : a['${t}'] === ${s}`}return r})).join(") && (")});`),t):[]}}function l(e=null,t={}){const s=new c(t);return Array.isArray(e)&&s.batch(e,"set"),s}export{l as haro}; \ No newline at end of file +const e=[8,9,"a","b"];function t(e){return JSON.parse(JSON.stringify(e,null,0))}function r(e,t){for(const r of e.entries())t(r[1],r[0]);return e}function s(e,t,r,s){let i;return i=e.includes(r)?e.split(r).sort(((e,t)=>e.localeCompare(t))).map((e=>(void 0!==t[e]?t[e]:"").toString().replace(new RegExp(s,"g"),"").toLowerCase())).join(r):t[e],i}function i(e,t,r,i,n,a){e.forEach((e=>{const h=t.get(e),o=s(e,n,r,a);if(h.has(o)){const e=h.get(o);e.delete(i),0===e.size&&h.delete(o)}}))}function n(e,t){return e instanceof Object&&t instanceof Object?r(Object.keys(t),(r=>{e[r]instanceof Object&&t[r]instanceof Object?e[r]=n(e[r],t[r]):Array.isArray(e[r])&&Array.isArray(t[r])?e[r]=e[r].concat(t[r]):e[r]=t[r]})):e=Array.isArray(e)&&Array.isArray(t)?e.concat(t):t,e}function a(){return(65536*(Math.random()+1)|0).toString(16).substring(1)}function h(e,t,s,i,n,a){r(a?[a]:e,(e=>{const a=t.get(e);if(e.includes(s)){r(e.split(s).reduce(((e,t,r)=>{const s=[];return(Array.isArray(n[t])?n[t]:[n[t]]).forEach((t=>0===r?s.push(t):e.forEach((e=>s.push(`${e}|${t}`))))),s}),[]),(e=>{a.has(e)||a.set(e,new Set),a.get(e).add(i)}))}else r(Array.isArray(n[e])?n[e]:[n[e]],(e=>{a.has(e)||a.set(e,new Set),a.get(e).add(i)}))}))}function o(){return a()+a()+"-"+a()+"-4"+a().substr(0,3)+"-"+e[Math.floor(4*Math.random())]+a().substr(0,3)+"-"+a()+a()+a()}class c{constructor({delimiter:e="|",id:t=o(),index:r=[],key:s="",pattern:i="\\s*|\\t*",versioning:n=!1}={}){return this.data=new Map,this.delimiter=e,this.id=t,this.index=r,this.indexes=new Map,this.key=s,this.pattern=i,this.size=0,this.versions=new Map,this.versioning=n,Object.defineProperty(this,"registry",{enumerable:!0,get:()=>Array.from(this.data.keys())}),this.reindex()}async batch(e,t="set",r=!1){let s;try{const i="del"===t?e=>this.del(e,!0,r):e=>this.set(null,e,!0,!0,r);s=await Promise.all(this.beforeBatch(e,t).map(i)),s=this.onbatch(s,t)}catch(e){throw this.onerror("batch",e),e}return s}beforeBatch(e){return e}beforeClear(){}beforeDelete(){}beforeSet(){}clear(){return this.beforeClear(),this.size=0,this.data.clear(),this.indexes.clear(),this.versions.clear(),this.reindex().onclear(),this}del(e,t=!1,r=!1,s=!1){if(!1===this.has(e))throw new Error("Record not found");const n=this.get(e,!0);return this.exec((async()=>{this.beforeDelete(e,t,r,s),i(this.index,this.indexes,this.delimiter,e,n,this.pattern),this.data.delete(e),--this.size}),(async()=>{this.ondelete(e,t,s,r),this.versioning&&this.versions.delete(e)}),(e=>{throw this.onerror("delete",e),e}))}dump(e="records"){let t;return t="records"===e?Array.from(this.entries()):Array.from(this.indexes).map((e=>(e[1]=Array.from(e[1]).map((e=>(e[1]=Array.from(e[1]),e))),e))),t}entries(){return this.data.entries()}async exec(e,t,r){let s;try{s=await t(await e())}catch(e){r(e)}return s}find(e,t=!1){const r=Object.keys(e).sort(((e,t)=>e.localeCompare(t))).join(this.delimiter),i=s(r,e,this.delimiter,this.pattern),n=Array.from((this.indexes.get(r)||new Map).get(i)||new Set).map((e=>this.get(e,t)));return t?n:this.list(...n)}filter(e,t=!1){const r=t?(e,t)=>t:(e,t)=>Object.freeze([e,Object.freeze(t)]),s=this.reduce(((t,s,i,n)=>(e.call(n,s)&&t.push(r(i,s)),t)),[]);return t?s:Object.freeze(s)}forEach(e,r){return this.data.forEach(((r,s)=>e(t(r),t(s))),r||this.data),this}get(e,r=!1){const s=t(this.data.get(e)||null);return r?s:this.list(e,s)}has(e,t=this.data){return t.has(e)}keys(){return this.data.keys()}limit(e=0,t=0,r=!1){const s=this.registry.slice(e,e+t).map((e=>this.get(e,r)));return r?s:this.list(...s)}list(...e){return Object.freeze(e.map((e=>Object.freeze(e))))}map(e,t=!1){const r=[];return this.forEach(((t,s)=>r.push(e(t,s)))),t?r:this.list(...r)}onbatch(e){return e}onclear(){}ondelete(){}onerror(){}onset(){}async override(e,t="records"){if("indexes"===t)this.indexes=new Map(e.map((e=>[e[0],new Map(e[1].map((e=>[e[0],new Set(e[1])])))])));else{if("records"!==t)throw new Error("Invalid type");this.indexes.clear(),this.data=new Map(e),this.size=this.data.size}return!0}reduce(e,t,r=!1){let s=t||this.data.keys().next().value;return this.forEach(((t,i)=>{s=e(s,t,i,this,r)}),this),s}reindex(e){const t=e?[e]:this.index;return e&&!1===this.index.includes(e)&&this.index.push(e),r(t,(e=>this.indexes.set(e,new Map))),this.forEach(((e,s)=>r(t,(t=>h(this.index,this.indexes,this.delimiter,s,e,t,this.pattern))))),this}search(e,t,s=!1){const i=new Map,n="function"==typeof e,a=e&&"function"==typeof e.test;return e&&r(t?Array.isArray(t)?t:[t]:this.index,(t=>{let r=this.indexes.get(t);r&&r.forEach(((r,h)=>{switch(!0){case n&&e(h,t):case a&&e.test(Array.isArray(h)?h.join(", "):h):case h===e:r.forEach((e=>{!i.has(e)&&this.has(e)&&i.set(e,this.get(e,s))}))}}))})),s?Array.from(i.values()):this.list(...Array.from(i.values()))}async set(e,r,s=!1,a=!1,c=!1,l=!1){let d,u=t(r);return this.exec((async()=>(null==e&&(e=this.key&&void 0!==u[this.key]?u[this.key]:o()),this.beforeSet(e,r,s,a,c,l),this.data.has(e)?(d=this.get(e,!0),i(this.index,this.indexes,this.delimiter,e,d,this.pattern),this.versioning&&this.versions.get(e).add(Object.freeze(t(d))),!1===a&&(u=n(t(d),u))):(++this.size,this.versioning&&this.versions.set(e,new Set)),this.data.set(e,u),h(this.index,this.indexes,this.delimiter,e,u,null,this.pattern),this.get(e))),(async e=>(this.onset(e,s,l,c),e)),(e=>{throw this.onerror("set",e),e}))}sort(e,t=!0){return t?Object.freeze(this.limit(0,this.size,!0).sort(e).map((e=>Object.freeze(e)))):this.limit(0,this.size,!0).sort(e)}sortBy(e,t=!1){const s=[],i=[];let n;return this.indexes.has(e)||this.reindex(e),n=this.indexes.get(e),n.forEach(((e,t)=>i.push(t))),r(i.sort(),(e=>n.get(e).forEach((e=>s.push(this.get(e,t)))))),t?s:this.list(...s)}toArray(e=!0){const s=Array.from(this.data.values()).map((e=>t(e)));return e&&(r(s,(e=>Object.freeze(e))),Object.freeze(s)),s}values(){return this.data.values()}where(e,t=!1,r="||"){const s=this.index.filter((t=>t in e));return s.length>0?this.filter(new Function("a",`return (${s.map((t=>{let s;if(Array.isArray(e[t]))s=`Array.isArray(a['${t}']) ? ${e[t].map((e=>`a['${t}'].includes(${"string"==typeof e?`'${e}'`:e})`)).join(` ${r} `)} : (${e[t].map((e=>`a['${t}'] === ${"string"==typeof e?`'${e}'`:e}`)).join(` ${r} `)})`;else if(e[t]instanceof RegExp)s=`Array.isArray(a['${t}']) ? a['${t}'].filter(i => ${e[t]}.test(a['${t}'])).length > 0 : ${e[t]}.test(a['${t}'])`;else{const r="string"==typeof e[t]?`'${e[t]}'`:e[t];s=`Array.isArray(a['${t}']) ? a['${t}'].includes(${r}) : a['${t}'] === ${r}`}return s})).join(") && (")});`),t):[]}}function l(e=null,t={}){const r=new c(t);return Array.isArray(e)&&r.batch(e,"set"),r}export{l as haro}; \ No newline at end of file diff --git a/dist/haro.js b/dist/haro.js index a074b15..17086e1 100644 --- a/dist/haro.js +++ b/dist/haro.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).haro={})}(this,(function(e){"use strict";const t=[8,9,"a","b"];function s(e){return JSON.parse(JSON.stringify(e,null,0))}function r(e,t){for(const s of e.entries())t(s[1],s[0]);return e}function i(e,t,s,r){let i;return i=e.includes(s)?e.split(s).sort(((e,t)=>e.localeCompare(t))).map((e=>(void 0!==t[e]?t[e]:"").toString().replace(new RegExp(r,"g"),"").toLowerCase())).join(s):t[e],i}function n(e,t,s,r,n,a){e.forEach((e=>{const h=t.get(e),o=i(e,n,s,a);if(h.has(o)){const e=h.get(o);e.delete(r),0===e.size&&h.delete(o)}}))}function a(e,t){return e instanceof Object&&t instanceof Object?r(Object.keys(t),(s=>{e[s]instanceof Object&&t[s]instanceof Object?e[s]=a(e[s],t[s]):Array.isArray(e[s])&&Array.isArray(t[s])?e[s]=e[s].concat(t[s]):e[s]=t[s]})):e=Array.isArray(e)&&Array.isArray(t)?e.concat(t):t,e}function h(){return(65536*(Math.random()+1)|0).toString(16).substring(1)}function o(e,t,s,n,a,h,o){r(h?[h]:e,(e=>{const h=t.get(e);if(Array.isArray(a[e])&&!e.includes(s))r(a[e],(e=>{h.has(e)||h.set(e,new Set),h.get(e).add(n)}));else{const t=i(e,a,s,o);null!=t&&(h.has(t)||h.set(t,new Set),h.get(t).add(n))}}))}function c(){return h()+h()+"-"+h()+"-4"+h().substr(0,3)+"-"+t[Math.floor(4*Math.random())]+h().substr(0,3)+"-"+h()+h()+h()}class d{constructor({delimiter:e="|",id:t=c(),index:s=[],key:r="",pattern:i="\\s*|\\t*",versioning:n=!1}={}){return this.data=new Map,this.delimiter=e,this.id=t,this.index=s,this.indexes=new Map,this.key=r,this.pattern=i,this.size=0,this.versions=new Map,this.versioning=n,Object.defineProperty(this,"registry",{enumerable:!0,get:()=>Array.from(this.data.keys())}),this.reindex()}async batch(e,t="set",s=!1){let r;try{const i="del"===t?e=>this.del(e,!0,s):e=>this.set(null,e,!0,!0,s);r=await Promise.all(this.beforeBatch(e,t).map(i)),r=this.onbatch(r,t)}catch(e){throw this.onerror("batch",e),e}return r}beforeBatch(e){return e}beforeClear(){}beforeDelete(){}beforeSet(){}clear(){return this.beforeClear(),this.size=0,this.data.clear(),this.indexes.clear(),this.versions.clear(),this.reindex().onclear(),this}del(e,t=!1,s=!1,r=!1){if(!1===this.has(e))throw new Error("Record not found");const i=this.get(e,!0);return this.exec((async()=>{this.beforeDelete(e,t,s,r),n(this.index,this.indexes,this.delimiter,e,i,this.pattern),this.data.delete(e),--this.size}),(async()=>{this.ondelete(e,t,r,s),this.versioning&&this.versions.delete(e)}),(e=>{throw this.onerror("delete",e),e}))}dump(e="records"){let t;return t="records"===e?Array.from(this.entries()):Array.from(this.indexes).map((e=>(e[1]=Array.from(e[1]).map((e=>(e[1]=Array.from(e[1]),e))),e))),t}entries(){return this.data.entries()}async exec(e,t,s){let r;try{r=await t(await e())}catch(e){s(e)}return r}find(e,t=!1){const s=Object.keys(e).sort(((e,t)=>e.localeCompare(t))).join(this.delimiter),r=i(s,e,this.delimiter,this.pattern),n=Array.from((this.indexes.get(s)||new Map).get(r)||new Set).map((e=>this.get(e,t)));return t?n:this.list(...n)}filter(e,t=!1){const s=t?(e,t)=>t:(e,t)=>Object.freeze([e,Object.freeze(t)]),r=this.reduce(((t,r,i,n)=>(e.call(n,r)&&t.push(s(i,r)),t)),[]);return t?r:Object.freeze(r)}forEach(e,t){return this.data.forEach(((t,r)=>e(s(t),s(r))),t||this.data),this}get(e,t=!1){const r=s(this.data.get(e)||null);return t?r:this.list(e,r)}has(e,t=this.data){return t.has(e)}keys(){return this.data.keys()}limit(e=0,t=0,s=!1){const r=this.registry.slice(e,e+t).map((e=>this.get(e,s)));return s?r:this.list(...r)}list(...e){return Object.freeze(e.map((e=>Object.freeze(e))))}map(e,t=!1){const s=[];return this.forEach(((t,r)=>s.push(e(t,r)))),t?s:this.list(...s)}onbatch(e){return e}onclear(){}ondelete(){}onerror(){}onset(){}async override(e,t="records"){if("indexes"===t)this.indexes=new Map(e.map((e=>[e[0],new Map(e[1].map((e=>[e[0],new Set(e[1])])))])));else{if("records"!==t)throw new Error("Invalid type");this.indexes.clear(),this.data=new Map(e),this.size=this.data.size}return!0}reduce(e,t,s=!1){let r=t||this.data.keys().next().value;return this.forEach(((t,i)=>{r=e(r,t,i,this,s)}),this),r}reindex(e){const t=e?[e]:this.index;return e&&!1===this.index.includes(e)&&this.index.push(e),r(t,(e=>this.indexes.set(e,new Map))),this.forEach(((e,s)=>r(t,(t=>o(this.index,this.indexes,this.delimiter,s,e,t,this.pattern))))),this}search(e,t,s=!1){const i=new Map,n="function"==typeof e,a=e&&"function"==typeof e.test;return e&&r(t?Array.isArray(t)?t:[t]:this.index,(t=>{let r=this.indexes.get(t);r&&r.forEach(((r,h)=>{switch(!0){case n&&e(h,t):case a&&e.test(Array.isArray(h)?h.join(", "):h):case h===e:r.forEach((e=>{!i.has(e)&&this.has(e)&&i.set(e,this.get(e,s))}))}}))})),s?Array.from(i.values()):this.list(...Array.from(i.values()))}async set(e,t,r=!1,i=!1,h=!1,d=!1){let l,f=s(t);return this.exec((async()=>(null==e&&(e=this.key&&void 0!==f[this.key]?f[this.key]:c()),this.beforeSet(e,t,r,i,h,d),this.data.has(e)?(l=this.get(e,!0),n(this.index,this.indexes,this.delimiter,e,l,this.pattern),this.versioning&&this.versions.get(e).add(Object.freeze(s(l))),!1===i&&(f=a(s(l),f))):(++this.size,this.versioning&&this.versions.set(e,new Set)),this.data.set(e,f),o(this.index,this.indexes,this.delimiter,e,f,null,this.pattern),this.get(e))),(async e=>(this.onset(e,r,d,h),e)),(e=>{throw this.onerror("set",e),e}))}sort(e,t=!0){return t?Object.freeze(this.limit(0,this.size,!0).sort(e).map((e=>Object.freeze(e)))):this.limit(0,this.size,!0).sort(e)}sortBy(e,t=!1){const s=[],i=[];let n;return this.indexes.has(e)||this.reindex(e),n=this.indexes.get(e),n.forEach(((e,t)=>i.push(t))),r(i.sort(),(e=>n.get(e).forEach((e=>s.push(this.get(e,t)))))),t?s:this.list(...s)}toArray(e=!0){const t=Array.from(this.data.values()).map((e=>s(e)));return e&&(r(t,(e=>Object.freeze(e))),Object.freeze(t)),t}values(){return this.data.values()}where(e,t=!1,s="||"){const r=this.index.filter((t=>t in e));return r.length>0?this.filter(new Function("a",`return (${r.map((t=>{let r;if(Array.isArray(e[t]))r=`Array.isArray(a['${t}']) ? ${e[t].map((e=>`a['${t}'].includes(${"string"==typeof e?`'${e}'`:e})`)).join(` ${s} `)} : (${e[t].map((e=>`a['${t}'] === ${"string"==typeof e?`'${e}'`:e}`)).join(` ${s} `)})`;else if(e[t]instanceof RegExp)r=`Array.isArray(a['${t}']) ? a['${t}'].filter(i => ${e[t]}.test(a['${t}'])).length > 0 : ${e[t]}.test(a['${t}'])`;else{const s="string"==typeof e[t]?`'${e[t]}'`:e[t];r=`Array.isArray(a['${t}']) ? a['${t}'].includes(${s}) : a['${t}'] === ${s}`}return r})).join(") && (")});`),t):[]}}e.haro=function(e=null,t={}){const s=new d(t);return Array.isArray(e)&&s.batch(e,"set"),s},Object.defineProperty(e,"__esModule",{value:!0})})); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).haro={})}(this,(function(e){"use strict";const t=[8,9,"a","b"];function s(e){return JSON.parse(JSON.stringify(e,null,0))}function r(e,t){for(const s of e.entries())t(s[1],s[0]);return e}function i(e,t,s,r){let i;return i=e.includes(s)?e.split(s).sort(((e,t)=>e.localeCompare(t))).map((e=>(void 0!==t[e]?t[e]:"").toString().replace(new RegExp(r,"g"),"").toLowerCase())).join(s):t[e],i}function n(e,t,s,r,n,a){e.forEach((e=>{const h=t.get(e),o=i(e,n,s,a);if(h.has(o)){const e=h.get(o);e.delete(r),0===e.size&&h.delete(o)}}))}function a(e,t){return e instanceof Object&&t instanceof Object?r(Object.keys(t),(s=>{e[s]instanceof Object&&t[s]instanceof Object?e[s]=a(e[s],t[s]):Array.isArray(e[s])&&Array.isArray(t[s])?e[s]=e[s].concat(t[s]):e[s]=t[s]})):e=Array.isArray(e)&&Array.isArray(t)?e.concat(t):t,e}function h(){return(65536*(Math.random()+1)|0).toString(16).substring(1)}function o(e,t,s,i,n,a){r(a?[a]:e,(e=>{const a=t.get(e);if(e.includes(s)){r(e.split(s).reduce(((e,t,s)=>{const r=[];return(Array.isArray(n[t])?n[t]:[n[t]]).forEach((t=>0===s?r.push(t):e.forEach((e=>r.push(`${e}|${t}`))))),r}),[]),(e=>{a.has(e)||a.set(e,new Set),a.get(e).add(i)}))}else r(Array.isArray(n[e])?n[e]:[n[e]],(e=>{a.has(e)||a.set(e,new Set),a.get(e).add(i)}))}))}function c(){return h()+h()+"-"+h()+"-4"+h().substr(0,3)+"-"+t[Math.floor(4*Math.random())]+h().substr(0,3)+"-"+h()+h()+h()}class d{constructor({delimiter:e="|",id:t=c(),index:s=[],key:r="",pattern:i="\\s*|\\t*",versioning:n=!1}={}){return this.data=new Map,this.delimiter=e,this.id=t,this.index=s,this.indexes=new Map,this.key=r,this.pattern=i,this.size=0,this.versions=new Map,this.versioning=n,Object.defineProperty(this,"registry",{enumerable:!0,get:()=>Array.from(this.data.keys())}),this.reindex()}async batch(e,t="set",s=!1){let r;try{const i="del"===t?e=>this.del(e,!0,s):e=>this.set(null,e,!0,!0,s);r=await Promise.all(this.beforeBatch(e,t).map(i)),r=this.onbatch(r,t)}catch(e){throw this.onerror("batch",e),e}return r}beforeBatch(e){return e}beforeClear(){}beforeDelete(){}beforeSet(){}clear(){return this.beforeClear(),this.size=0,this.data.clear(),this.indexes.clear(),this.versions.clear(),this.reindex().onclear(),this}del(e,t=!1,s=!1,r=!1){if(!1===this.has(e))throw new Error("Record not found");const i=this.get(e,!0);return this.exec((async()=>{this.beforeDelete(e,t,s,r),n(this.index,this.indexes,this.delimiter,e,i,this.pattern),this.data.delete(e),--this.size}),(async()=>{this.ondelete(e,t,r,s),this.versioning&&this.versions.delete(e)}),(e=>{throw this.onerror("delete",e),e}))}dump(e="records"){let t;return t="records"===e?Array.from(this.entries()):Array.from(this.indexes).map((e=>(e[1]=Array.from(e[1]).map((e=>(e[1]=Array.from(e[1]),e))),e))),t}entries(){return this.data.entries()}async exec(e,t,s){let r;try{r=await t(await e())}catch(e){s(e)}return r}find(e,t=!1){const s=Object.keys(e).sort(((e,t)=>e.localeCompare(t))).join(this.delimiter),r=i(s,e,this.delimiter,this.pattern),n=Array.from((this.indexes.get(s)||new Map).get(r)||new Set).map((e=>this.get(e,t)));return t?n:this.list(...n)}filter(e,t=!1){const s=t?(e,t)=>t:(e,t)=>Object.freeze([e,Object.freeze(t)]),r=this.reduce(((t,r,i,n)=>(e.call(n,r)&&t.push(s(i,r)),t)),[]);return t?r:Object.freeze(r)}forEach(e,t){return this.data.forEach(((t,r)=>e(s(t),s(r))),t||this.data),this}get(e,t=!1){const r=s(this.data.get(e)||null);return t?r:this.list(e,r)}has(e,t=this.data){return t.has(e)}keys(){return this.data.keys()}limit(e=0,t=0,s=!1){const r=this.registry.slice(e,e+t).map((e=>this.get(e,s)));return s?r:this.list(...r)}list(...e){return Object.freeze(e.map((e=>Object.freeze(e))))}map(e,t=!1){const s=[];return this.forEach(((t,r)=>s.push(e(t,r)))),t?s:this.list(...s)}onbatch(e){return e}onclear(){}ondelete(){}onerror(){}onset(){}async override(e,t="records"){if("indexes"===t)this.indexes=new Map(e.map((e=>[e[0],new Map(e[1].map((e=>[e[0],new Set(e[1])])))])));else{if("records"!==t)throw new Error("Invalid type");this.indexes.clear(),this.data=new Map(e),this.size=this.data.size}return!0}reduce(e,t,s=!1){let r=t||this.data.keys().next().value;return this.forEach(((t,i)=>{r=e(r,t,i,this,s)}),this),r}reindex(e){const t=e?[e]:this.index;return e&&!1===this.index.includes(e)&&this.index.push(e),r(t,(e=>this.indexes.set(e,new Map))),this.forEach(((e,s)=>r(t,(t=>o(this.index,this.indexes,this.delimiter,s,e,t,this.pattern))))),this}search(e,t,s=!1){const i=new Map,n="function"==typeof e,a=e&&"function"==typeof e.test;return e&&r(t?Array.isArray(t)?t:[t]:this.index,(t=>{let r=this.indexes.get(t);r&&r.forEach(((r,h)=>{switch(!0){case n&&e(h,t):case a&&e.test(Array.isArray(h)?h.join(", "):h):case h===e:r.forEach((e=>{!i.has(e)&&this.has(e)&&i.set(e,this.get(e,s))}))}}))})),s?Array.from(i.values()):this.list(...Array.from(i.values()))}async set(e,t,r=!1,i=!1,h=!1,d=!1){let l,u=s(t);return this.exec((async()=>(null==e&&(e=this.key&&void 0!==u[this.key]?u[this.key]:c()),this.beforeSet(e,t,r,i,h,d),this.data.has(e)?(l=this.get(e,!0),n(this.index,this.indexes,this.delimiter,e,l,this.pattern),this.versioning&&this.versions.get(e).add(Object.freeze(s(l))),!1===i&&(u=a(s(l),u))):(++this.size,this.versioning&&this.versions.set(e,new Set)),this.data.set(e,u),o(this.index,this.indexes,this.delimiter,e,u,null,this.pattern),this.get(e))),(async e=>(this.onset(e,r,d,h),e)),(e=>{throw this.onerror("set",e),e}))}sort(e,t=!0){return t?Object.freeze(this.limit(0,this.size,!0).sort(e).map((e=>Object.freeze(e)))):this.limit(0,this.size,!0).sort(e)}sortBy(e,t=!1){const s=[],i=[];let n;return this.indexes.has(e)||this.reindex(e),n=this.indexes.get(e),n.forEach(((e,t)=>i.push(t))),r(i.sort(),(e=>n.get(e).forEach((e=>s.push(this.get(e,t)))))),t?s:this.list(...s)}toArray(e=!0){const t=Array.from(this.data.values()).map((e=>s(e)));return e&&(r(t,(e=>Object.freeze(e))),Object.freeze(t)),t}values(){return this.data.values()}where(e,t=!1,s="||"){const r=this.index.filter((t=>t in e));return r.length>0?this.filter(new Function("a",`return (${r.map((t=>{let r;if(Array.isArray(e[t]))r=`Array.isArray(a['${t}']) ? ${e[t].map((e=>`a['${t}'].includes(${"string"==typeof e?`'${e}'`:e})`)).join(` ${s} `)} : (${e[t].map((e=>`a['${t}'] === ${"string"==typeof e?`'${e}'`:e}`)).join(` ${s} `)})`;else if(e[t]instanceof RegExp)r=`Array.isArray(a['${t}']) ? a['${t}'].filter(i => ${e[t]}.test(a['${t}'])).length > 0 : ${e[t]}.test(a['${t}'])`;else{const s="string"==typeof e[t]?`'${e[t]}'`:e[t];r=`Array.isArray(a['${t}']) ? a['${t}'].includes(${s}) : a['${t}'] === ${s}`}return r})).join(") && (")});`),t):[]}}e.haro=function(e=null,t={}){const s=new d(t);return Array.isArray(e)&&s.batch(e,"set"),s},Object.defineProperty(e,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/src/haro.js b/src/haro.js index 69c10bc..8f42bcc 100644 --- a/src/haro.js +++ b/src/haro.js @@ -67,28 +67,35 @@ function s () { return ((Math.random() + 1) * 0x10000 | 0).toString(16).substring(1); } -function setIndex (index, indexes, delimiter, key, data, indice, pattern) { +function setIndex (index, indexes, delimiter, key, data, indice) { each(!indice ? index : [indice], i => { const lindex = indexes.get(i); - if (Array.isArray(data[i]) && !i.includes(delimiter)) { - each(data[i], d => { - if (!lindex.has(d)) { - lindex.set(d, new Set()); + if (i.includes(delimiter)) { + const keys = i.split(delimiter), + results = keys.reduce((a, li, lidx) => { + const result = []; + + (Array.isArray(data[li]) ? data[li] : [data[li]]).forEach(lli => lidx === 0 ? result.push(lli) : a.forEach(x => result.push(`${x}|${lli}`))); + + return result; + }, []); + + each(results, c => { + if (!lindex.has(c)) { + lindex.set(c, new Set()); } - lindex.get(d).add(key); + lindex.get(c).add(key); }); } else { - const lidx = keyIndex(i, data, delimiter, pattern); - - if (lidx !== void 0 && lidx !== null) { - if (!lindex.has(lidx)) { - lindex.set(lidx, new Set()); + each(Array.isArray(data[i]) ? data[i] : [data[i]], d => { + if (!lindex.has(d)) { + lindex.set(d, new Set()); } - lindex.get(lidx).add(key); - } + lindex.get(d).add(key); + }); } }); }