UNPKG

pixiedb

Version:

A tiny in-memory javascript database with indexing and SQL like filters.

2 lines (1 loc) 15.4 kB
"use strict";var p$2=Object.defineProperty,s$2=(a,e,r)=>e in a?p$2(a,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[e]=r,t=(a,e,r)=>(s$2(a,typeof e!="symbol"?e+"":e,r),r);class PDBError extends Error{constructor(e,r){super(r),t(this,"name"),this.name=`${e}Error`}}function freeze(a){return Object.freeze(a)}function isNullOrUndefined(a){return a==null}function isArray(a){return Array.isArray(a)}function toArray(a){return Array.isArray(a)?a:a instanceof Set?Array.from(a):[a]}function remove(a,e){a.splice(a.indexOf(e),1)}function valArr(a){if(!isArray(a))throw new PDBError("Value","Invalid values")}function valPair(a){if(!isArray(a)||a.length!==2)throw new PDBError("Value","Invalid values")}function hasOwn(a,e){return Object.hasOwnProperty.call(a,e)}function deepClone(a){return JSON.parse(JSON.stringify(a))}function throttle(a,e=1e3,...r){let I;return function(){clearTimeout(I),I=setTimeout((...T)=>{a(...T),I=void 0},e,...r)}}var p$1=Object.defineProperty,E$1=(a,e,r)=>e in a?p$1(a,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[e]=r,v$1=(a,e,r)=>(E$1(a,typeof e!="symbol"?e+"":e,r),r);class EvEmit{constructor(e){v$1(this,"events",freeze({L:[],I:[],U:[],D:[],C:[],Q:[]})),v$1(this,"cEv"),this.setCEVTime(e)}setCEVTime(e){this.cEv=throttle(()=>this.emit("C"),e)}on(e,r){return toArray(e).forEach(I=>{hasOwn(this.events,I)&&this.events[I].push(r)}),r}offAll(){this.events=freeze({L:[],I:[],U:[],D:[],C:[],Q:[]})}off(e,r){return toArray(e).forEach(I=>hasOwn(this.events,I)&&remove(this.events[I],r)),r}emit(...e){const[r,...I]=e;hasOwn(this.events,r)&&setTimeout(()=>this.events[r].forEach(T=>T(r,I)),10),"IUD".includes(r)&&this.cEv()}}var W=(a,e,r)=>{if(!e.has(a))throw TypeError("Cannot "+r)},s$1=(a,e,r)=>(W(a,e,"read from private field"),r?r.call(a):e.get(a)),f$2=(a,e,r)=>{if(e.has(a))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(a):e.set(a,r)},l=(a,e,r,I)=>(W(a,e,"write to private field"),I?I.call(a,r):e.set(a,r),r),i=(a,e,r)=>(W(a,e,"access private method"),r),M,u,U,p,x,A,$,F,b$1,g,N,D$1,Q,q,J,Z,j,H,O,R,V,_,P,B$1,C,v,k,S$1,E,z,L,se,K$1,w$1;class ResultSet{constructor(e,r,I,T,G,tt="select"){f$2(this,J),f$2(this,j),f$2(this,O),f$2(this,V),f$2(this,P),f$2(this,C),f$2(this,k),f$2(this,E),f$2(this,L),f$2(this,K$1),f$2(this,M,[]),f$2(this,u,[]),f$2(this,U,!1),f$2(this,p,0),f$2(this,x,-1),f$2(this,A,!0),f$2(this,$,void 0),f$2(this,F,void 0),f$2(this,b$1,void 0),f$2(this,g,void 0),f$2(this,N,void 0),f$2(this,D$1,[]),f$2(this,Q,[]),f$2(this,q,void 0),l(this,q,e),l(this,F,r),l(this,b$1,I),l(this,g,T),l(this,$,tt),l(this,N,G??[])}delete(){return i(this,k,S$1).call(this,"where"),l(this,A,!1),i(this,P,B$1).call(this),i(this,C,v).call(this)}update(e){return hasOwn(e,s$1(this,F))&&delete e[s$1(this,F)],i(this,k,S$1).call(this,"where"),i(this,P,B$1).call(this),i(this,C,v).call(this,e)}data(){return i(this,k,S$1).call(this,"select"),i(this,P,B$1).call(this),i(this,E,z).call(this,s$1(this,u)),s$1(this,u).map(e=>i(this,O,R).call(this,i(this,V,_).call(this,e)))}single(){return i(this,k,S$1).call(this,"select"),i(this,P,B$1).call(this),i(this,E,z).call(this,s$1(this,u)),i(this,O,R).call(this,i(this,V,_).call(this,s$1(this,u)[0]))}range(e=0,r=-1){return e>=0&&l(this,p,e),r>=0&&l(this,x,r),s$1(this,Q).push("R"),this}count(){return l(this,A,!1),s$1(this,M).length?i(this,P,B$1).call(this):s$1(this,b$1).size}orderBy(e){return valArr(e),l(this,D$1,e.map(r=>{const I=isArray(r)?r:[r,"asc"];if(I.length!==2||typeof I[0]!="string"||!["asc","desc"].includes(I[1]))throw new PDBError("Value","Incorrect values for orderBy");return I})),s$1(this,Q).push("S"),i(this,P,B$1).call(this),i(this,L,se).call(this),this}eq(e,r){return i(this,K$1,w$1).call(this,"eq",e,r)}in(e,r){valArr(r);const I=new Set(r);return i(this,K$1,w$1).call(this,"in",e,I)}nin(e,r){valArr(r);const I=new Set(r);return i(this,K$1,w$1).call(this,"nin",e,I)}between(e,r){return valPair(r),i(this,K$1,w$1).call(this,"btw",e,r[0],r[1])}nbetween(e,r){return valPair(r),i(this,K$1,w$1).call(this,"nbtw",e,r[0],r[1])}neq(e,r){return i(this,K$1,w$1).call(this,"neq",e,r)}gt(e,r){return i(this,K$1,w$1).call(this,"gt",e,r)}gte(e,r){return i(this,K$1,w$1).call(this,"gte",e,r)}lt(e,r){return i(this,K$1,w$1).call(this,"lt",e,r)}lte(e,r){return i(this,K$1,w$1).call(this,"lte",e,r)}toJSON(e=!1){return i(this,k,S$1).call(this,"select"),l(this,A,e),this.data()}}M=new WeakMap,u=new WeakMap,U=new WeakMap,p=new WeakMap,x=new WeakMap,A=new WeakMap,$=new WeakMap,F=new WeakMap,b$1=new WeakMap,g=new WeakMap,N=new WeakMap,D$1=new WeakMap,Q=new WeakMap,q=new WeakMap,J=new WeakSet,Z=function(a,e,r="eq",I){let T,G;switch(r){case"eq":T=s$1(this,g)[a].get(e);break;case"in":G=s$1(this,g)[a].in(e);break;case"btw":if(I===void 0)break;G=s$1(this,g)[a].btw(e,I);break;case"gt":case"lt":case"gte":case"lte":const tt=/^gt/.test(r);G=s$1(this,g)[a][tt?"gt":"lt"](e,/e$/.test(r)),tt||G.reverse();break}G&&(s$1(this,q).isUniqIdx(a)?T=G:G.forEach(tt=>tt instanceof Set&&tt.forEach(X=>i(this,j,H).call(this,X)))),T?.forEach(tt=>i(this,j,H).call(this,tt))},j=new WeakSet,H=function(a){const e=s$1(this,b$1).get(a);e&&s$1(this,u).push(i(this,O,R).call(this,e))},O=new WeakSet,R=function(a,e){try{return(s$1(this,A)||e)&&a?s$1(this,q).cloneMethod(a):a}catch{}return a},V=new WeakSet,_=function(a){return s$1(this,N).length?s$1(this,N).reduce((e,r)=>(e[r]=a[r],e),{}):a},P=new WeakSet,B$1=function(){try{if(s$1(this,U))throw"";let a=!1,e=s$1(this,p),r=s$1(this,x);const I=s$1(this,M),T=I[0];if(!T){if(e===0&&r===1){const X=s$1(this,b$1).values().next().value;l(this,u,X?[X]:[])}else i(this,E,z).call(this);throw l(this,U,!0),""}if(T[1]===s$1(this,F)&&/^(eq|in)/.test(T[0])?((T[2]instanceof Set?T[2]:[T[2]]).forEach(X=>i(this,j,H).call(this,X)),a=!0):hasOwn(s$1(this,g),T[1])&&/btw|^(eq|gt|in|lt)/.test(T[0])&&(T[0]==="nbtw"&&(i(this,J,Z).call(this,T[1],T[2],"lt"),T[2]=T[3],T[0]="gt"),i(this,J,Z).call(this,T[1],T[2],T[0],T[3]),a=!0),a&&I.shift(),!I.length)throw a||l(this,u,i(this,E,z).call(this)),l(this,U,!0),"";const G=a?s$1(this,u):s$1(this,b$1).values();l(this,u,[]);let tt;for(const X of G)if(tt=!I.some(([st,Y,it,et])=>{switch(st){case"btw":return!(X[Y]>=it&&X[Y]<=et);case"eq":return X[Y]!==it;case"gt":return X[Y]<=it;case"gte":return X[Y]<it;case"in":return!it.has(X[Y]);case"lt":return X[Y]>=it;case"lte":return X[Y]>it;case"nbtw":return X[Y]>=it&&X[Y]<=et;case"neq":return X[Y]===it;case"nin":return it.has(X[Y]);default:throw new PDBError("Filter","Unsupported filter: "+st)}}),tt&&--e<0&&(s$1(this,u).push(X),r!==-1&&--r<=0))break;l(this,U,!0),l(this,p,0),l(this,x,-1)}catch(a){if(a)throw a}return s$1(this,u).length},C=new WeakSet,v=function(a){i(this,k,S$1).call(this,"where");const e=[];let r;const I=s$1(this,g),T=s$1(this,F);let G,tt=Object.keys(I);return a&&(tt=tt.filter(X=>hasOwn(a,X))),s$1(this,u).forEach(X=>{tt.forEach(Y=>{if(G=s$1(this,q).isUniqIdx(Y),a){if(X[Y]===a[Y])return;if(G){I[Y].set(a[Y],X[T]);return}r=I[Y].get(a[Y]),r||I[Y].set(a[Y],r=new Set),r.add(X[T])}if(G)I[Y].delete(X[Y]);else{const it=I[Y].getNode(X[Y]);it&&it.value instanceof Set&&(r=it.value,r.delete(X[T]),r.size||I[Y].deleteNode(it))}});let st=X;if(a){Object.assign(X,a),s$1(this,b$1).set(X[T],X);const Y=i(this,O,R).call(this,st);st=i(this,O,R).call(this,X,!0),s$1(this,q).emit("U",st,Y)}else s$1(this,b$1).delete(X[T]),s$1(this,q).emit("D",X);e.push(st)}),e},k=new WeakSet,S$1=function(a){if(s$1(this,$)!==a)throw new PDBError("Action",`unable to perform this action in "${a}"`)},E=new WeakSet,z=function(a=[...s$1(this,b$1).values()]){return l(this,u,s$1(this,p)!==0||s$1(this,x)!==-1?a.slice(s$1(this,p),s$1(this,x)===-1?void 0:s$1(this,p)+s$1(this,x)):a),l(this,p,0),l(this,x,-1),s$1(this,u)},L=new WeakSet,se=function(){const a=s$1(this,D$1).length;a&&(i(this,k,S$1).call(this,"select"),s$1(this,u).sort((e,r)=>{let I=0;for(let T=0;T<a;T++){const G=s$1(this,D$1)[T],tt=a-T,[X,st]=G,Y=isNullOrUndefined(e[X])?0:e[X],it=isNullOrUndefined(r[X])?0:r[X];let et=Y===it?0:Y<it?-1:1;et*=tt,st==="desc"&&(et*=-1),I+=et}return I}),l(this,D$1,[]))},K$1=new WeakSet,w$1=function(...a){const e=s$1(this,Q).at(-1);if(e&&e!=="F")throw new PDBError("Action","Unable to add filter");return s$1(this,M).push(a),this};var h=Object.defineProperty,f$1=(a,e,r)=>e in a?h(a,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[e]=r,s=(a,e,r)=>(f$1(a,typeof e!="symbol"?e+"":e,r),r);class BinaryIndex{constructor(){s(this,"root",null),s(this,"mn",null),s(this,"mx",null)}set(e,r,I=!0){const T=new o$1(e,r);let G=this.root;if(G){for(;;)if(e===G.key){if(I){G.value=r;break}return!1}else if(e<G.key)if(G.left)G=G.left;else{G.left=T,T.parent=G;break}else if(G.right)G=G.right;else{G.right=T,T.parent=G;break}this.fixTree(T)}else this.root=T,this.root.isRed=!1;return this.setMinMax(T),!0}setMinMax(e){(!this.mx||this.mx.key<e.key)&&(this.mx=e),(!this.mn||this.mn.key>e.key)&&(this.mn=e)}get(e){return this.getNode(e)?.value}btw(e,r){let I=this.root;if(!I)return[];const T=[];let G=[];for(;;)if(I)G.push(I),I=I.left;else if(G.length){if(I=G.pop(),I.key>=e&&I.key<=r)T.push(I.value);else if(I.key>r)break;I=I.right}else break;return T}in(e){const r=[];for(const I of e){const T=this.getNode(I);T&&r.push(T.value)}return r}trav(e){let r=this.root,I;for(;r;)if(I=e(r.key,r.value),I>0)r=r.right;else if(I<0)r=r.left;else return}lt(e,r){const I=[],T=[];let G=this.root;for(;G;)G.key<e||r&&G.key===e?(T.push(G),G=G.right):G=G.left;for(;T.length>0;)for(G=T.shift(),I.push(G.value),G=G.left;G;)T.push(G),G=G.right;return I}gt(e,r){const I=[];let T=this.root;if(!T||e>=this.maxNode().key)return I;const G=[];for(;T;)T.key>e||r&&T.key===e?(G.push(T),T=T.left):T=T.right;for(;G.length>0;)for(T=G.pop(),I.push(T.value),T=T.right;T;)G.push(T),T=T.left;return I}delete(e){const r=this.getNode(e);if(r)return this.deleteNode(r),r.value}fixTree(e){for(;e&&e.parent&&e.parent.isRed;){let r;if(e.parent===e.parent.parent.left?r=e.parent.parent.right:r=e.parent.parent.left,r&&r.isRed)e.parent.isRed=!1,r.isRed=!1,e=e.parent.parent;else{e===e.parent.right&&e.parent===e.parent.parent.left?(e=e.parent,this.leftRotate(e)):e===e.parent.left&&e.parent===e.parent.parent.right&&(e=e.parent,this.rightRotate(e)),e.parent.isRed=!1;const I=e.parent.parent;I&&(I.isRed=!0,e===e.parent.left?this.rightRotate(I):this.leftRotate(I))}}this.root.isRed=!1}leftRotate(e){const r=e.right;e.right=r.left,r.left&&(r.left.parent=e),r.parent=e.parent,e.parent?e===e.parent.left?e.parent.left=r:e.parent.right=r:this.root=r,r.left=e,e.parent=r}rightRotate(e){const r=e.left;e.left=r.right,r.right&&(r.right.parent=e),r.parent=e.parent,e.parent?e===e.parent.left?e.parent.left=r:e.parent.right=r:this.root=r,r.right=e,e.parent=r}getNode(e){let r=this.mn;if(r){if(r.key===e)return r;if(r.key>e)return}if(r=this.mx,r){if(r.key===e)return r;if(r.key<e)return}for(r=this.root;r;){if(e===r.key)return r;e<r.key?r=r.left:r=r.right}}minFrom(e){let r=e;for(;r.left;)r=r.left;return r}maxNode(){if(this.mx)return this.mx;let e=this.root;for(;e&&e.right;)e=e.right;return this.mx=e}minNode(){return this.mn?this.mn:this.root?this.mn=this.minFrom(this.root):null}min(){const e=this.minNode();if(e)return[e?.key,e?.value]}max(){const e=this.maxNode();if(e)return[e?.key,e?.value]}deleteNode(e){let r=null,I=null;e.left?e.right?(I=this.minFrom(e.right),I!==e.right&&(r=I,this.transplant(I,I.right),I.right=e.right,I.right.parent=I),this.transplant(e,I),I.left=e.left,I.left.parent=I,I.isRed=e.isRed):I=e.left:I=e.right,e===this.root?this.root=I:r?r.parent=e.parent:this.transplant(e,I),e.isRed||this.fixDeletion(I===null?e:I),this.mx===e&&(this.mx=null),this.mn===e&&(this.mn=null)}transplant(e,r){e.parent?e===e.parent.left?e.parent.left=r:e.parent.right=r:this.root=r,r&&(r.parent=e.parent)}fixDeletion(e){for(;e!==this.root&&e&&!e.isRed;)if(e===e.parent?.left){let r=e.parent.right;r?.isRed&&(r.isRed=!1,e.parent.isRed=!0,this.leftRotate(e.parent),r=e.parent.right),r?(!r.left||!r.left.isRed)&&(!r.right||!r.right.isRed)?(r.isRed=!0,e=e.parent):((!r.right||!r.right.isRed)&&(r.left.isRed=!1,r.isRed=!0,this.rightRotate(r),r=e.parent.right),r.isRed=e.parent.isRed,e.parent.isRed=!1,r.right.isRed=!1,this.leftRotate(e.parent),e=this.root):e=e.parent}else{let r=e.parent?.left;r?.isRed&&(r.isRed=!1,e.parent.isRed=!0,this.rightRotate(e.parent),r=e.parent?.left),r?(!r.left||!r.left.isRed)&&(!r.right||!r.right.isRed)?(r.isRed=!0,e=e.parent):((!r.left||!r.left.isRed)&&(r.right.isRed=!1,r.isRed=!0,this.leftRotate(r),r=e.parent?.left),r.isRed=e.parent.isRed,e.parent.isRed=!1,r.left.isRed=!1,this.rightRotate(e.parent),e=this.root):e=e.parent}e&&(e.isRed=!1)}clear(){this.root=this.mx=this.mn=null}}let o$1=class{constructor(e,r,I=!0){s(this,"key"),s(this,"value"),s(this,"isRed"),s(this,"left"),s(this,"right"),s(this,"parent"),this.key=e,this.value=r,this.isRed=I,this.left=this.right=this.parent=null}};var B=Object.defineProperty,D=(a,e,r)=>e in a?B(a,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[e]=r,m=(a,e,r)=>(D(a,typeof e!="symbol"?e+"":e,r),r),b=(a,e,r)=>{if(!e.has(a))throw TypeError("Cannot "+r)},n=(a,e,r)=>(b(a,e,"read from private field"),r?r.call(a):e.get(a)),f=(a,e,r)=>{if(e.has(a))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(a):e.set(a,r)},w=(a,e,r,I)=>(b(a,e,"write to private field"),I?I.call(a,r):e.set(a,r),r),S=(a,e,r)=>(b(a,e,"access private method"),r),y,o,d,c,K;class PixieDb extends EvEmit{constructor(e,r=[],I){super(200),f(this,c),m(this,"key"),f(this,y,freeze(new Map)),m(this,"cloneMethod",deepClone),f(this,o,void 0),f(this,d,void 0),this.key=e;const T=new Set([this.key]);r.push(e);const G=Object.create(null);r.forEach(tt=>{typeof tt=="object"&&tt.unique&&T.add(tt.name),G[typeof tt=="object"?tt.name:tt]=new BinaryIndex}),w(this,d,new RegExp(`^(${toArray(T).map(tt=>tt.toString().replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|")})$`)),w(this,o,freeze(G)),I&&this.load(I)}select(e){return S(this,c,K).call(this,isArray(e)?e:[])}where(){return S(this,c,K).call(this,[],"where")}insert(e,{silent:r,clone:I,upsert:T}={}){if(typeof e!="object")throw new PDBError("Value","Value must be an object or object array");let G;const tt=toArray(e),X=[],st=n(this,o),Y=this.key,it=this.indexes;return tt.forEach(et=>{try{if(n(this,y).get(et[Y])){T&&this.where().eq(this.key,et[this.key]).update(et).length&&X.push(et);return}it.forEach(rt=>{if(hasOwn(st,rt)){if(this.isUniqIdx(rt)){st[rt].set(et[rt],et[Y]);return}G=st[rt].get(et[rt]),G||st[rt].set(et[rt],G=new Set),G.add(et[Y])}}),n(this,y).set(et[Y],I===!1?et:this.cloneMethod(et)),r||this.emit("I",et),X.push(et)}catch{}}),isArray(e)?X:X[0]}load(e,r=!1){r&&(n(this,y).clear(),Object.values(n(this,o)).forEach(I=>I.clear())),this.insert(e,{silent:!0,clone:!1}),this.emit("L")}get(e){return n(this,y).get(e)}data(e=!0){const r=[...n(this,y).values()];return e?this.cloneMethod(r):r}get indexes(){return Object.keys(n(this,o))}isUniqIdx(e){return n(this,d).test(e.toString())}close(e=!1){n(this,y).clear(),Object.keys(n(this,o)).forEach(r=>{hasOwn(n(this,o),r)&&n(this,o)[r].clear()}),e||this.emit("Q"),this.offAll()}toJSON(){return{key:this.key,indexes:this.indexes.map(e=>this.isUniqIdx(e)?{name:e,unique:!0}:e),data:this.data()}}}y=new WeakMap,o=new WeakMap,d=new WeakMap,c=new WeakSet,K=function(a=[],e){return new ResultSet(this,this.key,n(this,y),n(this,o),a,e)},exports.PixieDb=PixieDb;