From 877cd5494eaefe5828e4404df23573f7752a4cb4 Mon Sep 17 00:00:00 2001 From: Ewout Stortenbeker Date: Wed, 12 Feb 2020 18:09:44 +0100 Subject: [PATCH] new browser build --- dist/browser.js | 51 ++++++++++++++++++++++++++++++++------------- dist/browser.min.js | 2 +- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/dist/browser.js b/dist/browser.js index e9697ee..a001cd2 100644 --- a/dist/browser.js +++ b/dist/browser.js @@ -640,6 +640,8 @@ class DataReference { let authorized = this.db.api.subscribe(this.path, event, cb.ours); const allSubscriptionsStoppedCallback = () => { + let callbacks = this[_private].callbacks; + callbacks.splice(callbacks.indexOf(cb), 1); this.db.api.unsubscribe(this.path, event, cb.ours); }; if (authorized instanceof Promise) { @@ -2243,12 +2245,14 @@ class TypeMappings { } if (typeof options.serializer === 'undefined') { - if (typeof type.prototype.serialize === 'function') { - // Use .serialize instance method - options.serializer = type.prototype.serialize; - } + // if (typeof type.prototype.serialize === 'function') { + // // Use .serialize instance method + // options.serializer = type.prototype.serialize; + // } + + // Use object's serialize method upon serialization (if available) } - if (typeof options.serializer === 'string') { + else if (typeof options.serializer === 'string') { if (typeof type.prototype[options.serializer] === 'function') { options.serializer = type.prototype[options.serializer]; } @@ -2299,6 +2303,9 @@ class TypeMappings { if (this.serializer) { obj = this.serializer.call(obj, ref, obj); } + else if (obj && typeof obj.serialize === 'function') { + obj = obj.serialize(ref, obj); + } return obj; } }; @@ -5103,7 +5110,7 @@ module.exports = { const { debug, ID, PathReference, PathInfo, ascii85 } = require('acebase-core'); const { NodeInfo } = require('./node-info'); const { VALUE_TYPES } = require('./node-value-types'); -const { Storage, StorageSettings } = require('./storage'); +const { Storage, StorageSettings, NodeNotFoundError } = require('./storage'); class LocalStorageSettings extends StorageSettings { constructor(settings) { @@ -5178,7 +5185,7 @@ class LocalStorage extends Storage { } }) .then(() => { - return this.indexes.load(); + return this.indexes.supported && this.indexes.load(); }) .then(() => { this.emit('ready'); @@ -5724,15 +5731,15 @@ class LocalStorage extends Storage { const targetRow = this._readNode(path); if (!targetRow) { // Lookup parent node - if (path === '') { return null; } // path is root. There is no parent. + if (path === '') { return { value: null }; } // path is root. There is no parent. return lock.moveToParent() .then(parentLock => { lock = parentLock; let parentNode = this._readNode(pathInfo.parentPath); - if ([VALUE_TYPES.OBJECT, VALUE_TYPES.ARRAY].includes(parentNode.type) && pathInfo.key in parentNode) { - return parentNode[pathInfo.key]; + if (parentNode && [VALUE_TYPES.OBJECT, VALUE_TYPES.ARRAY].includes(parentNode.type) && pathInfo.key in parentNode) { + return { revision: parentNode.revision, value: parentNode.value[pathInfo.key] }; } - return null; + return { value: null }; }); } @@ -5842,8 +5849,6 @@ class LocalStorage extends Storage { throw new Error(`multiple records found for non-object value!`); } - lock.release(); - // Post process filters to remove any data that got though because they were // not stored in dedicated records. This will happen with smaller values because // they are stored inline in their parent node. @@ -5886,6 +5891,10 @@ class LocalStorage extends Storage { } return result; }) + .then(result => { + lock.release(); + return result; + }) .catch(err => { lock.release(); throw err; @@ -6291,6 +6300,16 @@ class Storage extends EventEmitter { const _indexes = []; const storage = this; this.indexes = { + /** + * Tests if (the default storage implementation of) indexes are supported in the environment. + * They are currently only supported when running in Node.js because they use the fs filesystem. + * TODO: Implement storage specific indexes (eg in SQLite, MySQL, MSSQL, in-memory) + */ + get supported() { + const pfs = require('./promise-fs'); + return pfs && pfs.hasFileSystem; + }, + /** * Creates an index on specified path and key(s) * @param {string} path location of objects to be indexed. Eg: "users" to index all children of the "users" node; or "chats/*\/members" to index all members of all chats @@ -6594,6 +6613,10 @@ class Storage extends EventEmitter { } // end of constructor + get path() { + return `${this.settings.path}/${this.name}.acebase`; + } + // /** // * Once storage is ready for use, the optional callback will fire // * and the returned promise will resolve. @@ -7094,7 +7117,7 @@ class Storage extends EventEmitter { * @param {string[]} [options.exclude] child paths to exclude * @param {boolean} [options.child_objects] whether to inlcude child objects and arrays * @param {string} [options.tid] optional transaction id for node locking purposes - * @returns {Promise<{ revision: string, value: any}>} + * @returns {Promise<{ revision?: string, value: any}>} */ getNode(path, options = { include: undefined, exclude: undefined, child_objects: true, tid: undefined }) { throw new Error(`This method must be implemented by subclass`); diff --git a/dist/browser.min.js b/dist/browser.min.js index 4c004f1..3d2ee50 100644 --- a/dist/browser.min.js +++ b/dist/browser.min.js @@ -1 +1 @@ -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,(function(r){var n=e[i][1][r];return o(n||r)}),p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i=7&&stringLength<=10)return true;return false};cuid.fingerprint=fingerprint;module.exports=cuid},{"./lib/fingerprint.js":2,"./lib/pad.js":3}],2:[function(require,module,exports){var pad=require("./pad.js");var env=typeof window==="object"?window:self;var globalCount=Object.keys(env).length;var mimeTypesLength=navigator.mimeTypes?navigator.mimeTypes.length:0;var clientId=pad((mimeTypesLength+navigator.userAgent.length).toString(36)+globalCount.toString(36),4);module.exports=function fingerprint(){return clientId}},{"./pad.js":3}],3:[function(require,module,exports){module.exports=function pad(num,size){var s="000000000"+num;return s.substr(s.length-size)}},{}],4:[function(require,module,exports){const{EventEmitter:EventEmitter}=require("events");const{DataReference:DataReference,DataReferenceQuery:DataReferenceQuery}=require("./data-reference");const{TypeMappings:TypeMappings}=require("./type-mappings");class AceBaseSettings{constructor(options){this.logLevel=options.logLevel||"log"}}class AceBaseBase extends EventEmitter{constructor(dbname,options){super();if(!options){options={}}this.once("ready",()=>{this._ready=true});this.types=new TypeMappings(this)}ready(callback=undefined){if(this._ready===true){callback&&callback();return Promise.resolve()}else{let resolve;const promise=new Promise(res=>resolve=res);this.on("ready",()=>{resolve();callback&&callback()});return promise}}get isReady(){return this._ready===true}ref(path){return new DataReference(this,path)}get root(){return this.ref("")}query(path){const ref=new DataReference(this,path);return new DataReferenceQuery(ref)}get indexes(){return{get:()=>{return this.api.getIndexes()},create:(path,key,options)=>{return this.api.createIndex(path,key,options)}}}}module.exports={AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings}},{"./data-reference":7,"./type-mappings":16,events:40}],5:[function(require,module,exports){class Api{stats(options=undefined){}subscribe(path,event,callback){}unsubscribe(path,event,callback){}update(path,updates){}set(path,value){}get(path,options){}exists(path){}query(path,query,options){}createIndex(path,key){}getIndexes(){}}module.exports={Api:Api}},{}],6:[function(require,module,exports){const c=function(input,length,result){var i,j,n,b=[0,0,0,0,0];for(i=0;i";return ret},decode:function(input){if(!input.startsWith("<~")||!input.endsWith("~>")){throw new Error("Invalid input string")}input=input.substr(2,input.length-4);var n=input.length,r=[],b=[0,0,0,0,0],i,j,t,x,y,d;for(i=0;i>>=8;y=t&255;t>>>=8;r.push(t>>>8,t&255,y,x);for(j=d;j<5;++j,r.pop());i+=4}const data=new Uint8Array(r);return data.buffer.slice(data.byteOffset,data.byteOffset+data.byteLength)}};module.exports=ascii85},{}],7:[function(require,module,exports){const{DataSnapshot:DataSnapshot}=require("./data-snapshot");const{EventStream:EventStream,EventPublisher:EventPublisher}=require("./subscription");const{ID:ID}=require("./id");const debug=require("./debug");const{PathInfo:PathInfo}=require("./path-info");class DataRetrievalOptions{constructor(options){if(!options){options={}}if(typeof options.include!=="undefined"&&!(options.include instanceof Array)){throw new TypeError(`options.include must be an array`)}if(typeof options.exclude!=="undefined"&&!(options.exclude instanceof Array)){throw new TypeError(`options.exclude must be an array`)}if(typeof options.child_objects!=="undefined"&&typeof options.child_objects!=="boolean"){throw new TypeError(`options.child_objects must be a boolean`)}this.include=options.include||undefined;this.exclude=options.exclude||undefined;this.child_objects=typeof options.child_objects==="boolean"?options.child_objects:undefined}}class QueryDataRetrievalOptions extends DataRetrievalOptions{constructor(options){super(options);if(typeof options.snapshots!=="undefined"&&typeof options.snapshots!=="boolean"){throw new TypeError(`options.snapshots must be an array`)}this.snapshots=typeof options.snapshots==="boolean"?options.snapshots:undefined}}const _private=Symbol("private");class DataReference{constructor(db,path,vars){if(!path){path=""}path=path.replace(/^\/|\/$/g,"");const pathInfo=PathInfo.get(path);const key=pathInfo.key;const callbacks=[];this[_private]={get path(){return path},get key(){return key},get callbacks(){return callbacks},vars:vars||{}};this.db=db}get path(){return this[_private].path}get key(){return this[_private].key}get parent(){let currentPath=PathInfo.fillVariables2(this.path,this.vars);const info=PathInfo.get(currentPath);if(info.parentPath===null){return null}return new DataReference(this.db,info.parentPath)}get vars(){return this[_private].vars}child(childPath){childPath=childPath.replace(/^\/|\/$/g,"");const currentPath=PathInfo.fillVariables2(this.path,this.vars);const targetPath=PathInfo.getChildPath(currentPath,childPath);return new DataReference(this.db,targetPath)}set(value,onComplete=undefined){if(this.isWildcardPath){throw new Error(`Cannot set the value of a path with wildcards and/or variables`)}if(this.parent===null){throw new Error(`Cannot set the root object. Use update, or set individual child properties`)}if(typeof value==="undefined"){throw new TypeError(`Cannot store value undefined`)}value=this.db.types.serialize(this.path,value);return this.db.api.set(this.path,value).then(res=>{if(typeof onComplete==="function"){try{onComplete(null,this)}catch(err){console.error(`Error in onComplete callback:`,err)}}}).catch(err=>{if(typeof onComplete==="function"){try{onComplete(err)}catch(err){console.error(`Error in onComplete callback:`,err)}}else{throw err}}).then(()=>{return this})}update(updates,onComplete=undefined){if(this.isWildcardPath){throw new Error(`Cannot update the value of a path with wildcards and/or variables`)}let promise;if(typeof updates!=="object"||updates instanceof Array||updates instanceof ArrayBuffer||updates instanceof Date){promise=this.set(updates)}else{updates=this.db.types.serialize(this.path,updates);promise=this.db.api.update(this.path,updates)}return promise.then(()=>{if(typeof onComplete==="function"){try{onComplete(null,this)}catch(err){console.error(`Error in onComplete callback:`,err)}}}).catch(err=>{if(typeof onComplete==="function"){try{onComplete(err)}catch(err){console.error(`Error in onComplete callback:`,err)}}else{throw err}}).then(()=>{return this})}transaction(callback){if(this.isWildcardPath){throw new Error(`Cannot start a transaction on a path with wildcards and/or variables`)}let cb=currentValue=>{currentValue=this.db.types.deserialize(this.path,currentValue);const snap=new DataSnapshot(this,currentValue);let newValue;try{newValue=callback(snap)}catch(err){return}if(newValue instanceof Promise){return newValue.then(val=>{return this.db.types.serialize(this.path,val)})}else{return this.db.types.serialize(this.path,newValue)}};return this.db.api.transaction(this.path,cb).then(result=>{return this})}on(event,callback,cancelCallbackOrContext,context){if(this.path===""&&["value","notify_value","child_changed","notify_child_changed"].includes(event)){console.warn(`WARNING: Listening for value and child_changed events on the root node is a bad practice`)}const cancelCallback=typeof cancelCallbackOrContext==="function"&&cancelCallbackOrContext;context=typeof cancelCallbackOrContext==="object"?cancelCallbackOrContext:context;const useCallback=typeof callback==="function";let eventPublisher=null;const eventStream=new EventStream(publisher=>{eventPublisher=publisher});let cb={subscr:eventStream,original:callback,ours:(err,path,newValue,oldValue)=>{if(err){debug.error(`Error getting data for event ${event} on path "${path}"`,err);return}let ref=this.db.ref(path);ref[_private].vars=PathInfo.extractVariables(this.path,path);let callbackObject;if(event.startsWith("notify_")){callbackObject=ref}else{const isRemoved=event==="child_removed";const val=this.db.types.deserialize(path,isRemoved?oldValue:newValue);const snap=new DataSnapshot(ref,val,isRemoved);callbackObject=snap}useCallback&&callback.call(context||null,callbackObject);let keep=eventPublisher.publish(callbackObject);if(!keep&&!useCallback){let callbacks=this[_private].callbacks;callbacks.splice(callbacks.indexOf(cb),1);this.db.api.unsubscribe(this.path,event,cb.ours)}}};this[_private].callbacks.push(cb);let authorized=this.db.api.subscribe(this.path,event,cb.ours);const allSubscriptionsStoppedCallback=()=>{this.db.api.unsubscribe(this.path,event,cb.ours)};if(authorized instanceof Promise){authorized.then(()=>{eventPublisher.start(allSubscriptionsStoppedCallback)}).catch(err=>{let callbacks=this[_private].callbacks;callbacks.splice(callbacks.indexOf(cb),1);this.db.api.unsubscribe(this.path,event,cb.ours);eventPublisher.cancel(err.message);cancelCallback&&cancelCallback(err.message)})}else{eventPublisher.start(allSubscriptionsStoppedCallback)}if(callback&&!this.isWildcardPath){if(event==="value"){this.get(snap=>{eventPublisher.publish(snap);useCallback&&callback(snap)})}else if(event==="child_added"){this.get(snap=>{const val=snap.val();if(val===null||typeof val!=="object"){return}Object.keys(val).forEach(key=>{let childSnap=new DataSnapshot(this.child(key),val[key]);eventPublisher.publish(childSnap);useCallback&&callback(childSnap)})})}}return eventStream}off(event=undefined,callback=undefined){const callbacks=this[_private].callbacks;if(callback){const cb=callbacks.find(cb=>cb.original===callback);if(!cb){debug.error(`Can't find specified callback to unsubscribe from (path: "${this.path}", event: ${event}, callback: ${callback})`);return}callbacks.splice(callbacks.indexOf(cb),1);callback=cb.ours;cb.subscr.unsubscribe(callback)}else{callbacks.splice(0,callbacks.length).forEach(cb=>{cb.subscr.unsubscribe()})}this.db.api.unsubscribe(this.path,event,callback);return this}get(optionsOrCallback=undefined,callback=undefined){if(this.isWildcardPath){throw new Error(`Cannot get the value of a path with wildcards and/or variables. Use .query() instead`)}callback=typeof optionsOrCallback==="function"?optionsOrCallback:typeof callback==="function"?callback:undefined;const options=typeof optionsOrCallback==="object"?optionsOrCallback:undefined;const promise=this.db.api.get(this.path,options).then(value=>{value=this.db.types.deserialize(this.path,value);const snapshot=new DataSnapshot(this,value);return snapshot});if(callback){promise.then(callback);return}else{return promise}}once(event,options){if(event==="value"&&!this.isWildcardPath){return this.get(options)}return new Promise((resolve,reject)=>{const callback=snap=>{this.off(event,snap);resolve(snap)};this.on(event,callback)})}push(value=undefined,onComplete=undefined){if(this.isWildcardPath){throw new Error(`Cannot push to a path with wildcards and/or variables`)}const id=ID.generate();const ref=this.child(id);ref.__pushed=true;if(typeof value!=="undefined"){return ref.set(value,onComplete).then(res=>ref)}else{return ref}}remove(){if(this.isWildcardPath){throw new Error(`Cannot remove a path with wildcards and/or variables. Use query().remove instead`)}if(this.parent===null){throw new Error(`Cannot remove the top node`)}return this.set(null)}exists(){if(this.isWildcardPath){throw new Error(`Cannot push to a path with wildcards and/or variables`)}return this.db.api.exists(this.path)}get isWildcardPath(){return this.path.indexOf("*")>=0||this.path.indexOf("$")>=0}query(){return new DataReferenceQuery(this)}reflect(type,args){if(this.pathHasVariables){throw new Error(`Cannot reflect on a path with wildcards and/or variables`)}return this.db.api.reflect(this.path,type,args)}export(stream,options={format:"json"}){return this.db.api.export(this.path,stream,options)}}class DataReferenceQuery{constructor(ref){this.ref=ref;this[_private]={filters:[],skip:0,take:0,order:[]}}filter(key,op,compare){if((op==="in"||op==="!in")&&(!(compare instanceof Array)||compare.length===0)){throw new Error(`${op} filter for ${key} must supply an Array compare argument containing at least 1 value`)}if((op==="between"||op==="!between")&&(!(compare instanceof Array)||compare.length!==2)){throw new Error(`${op} filter for ${key} must supply an Array compare argument containing 2 values`)}if((op==="matches"||op==="!matches")&&!(compare instanceof RegExp)){throw new Error(`${op} filter for ${key} must supply a RegExp compare argument`)}if((op==="contains"||op==="!contains")&&(typeof compare==="object"&&!(compare instanceof Array)&&!(compare instanceof Date)||compare instanceof Array&&compare.length===0)){throw new Error(`${op} filter for ${key} must supply a simple value or (non-zero length) array compare argument`)}this[_private].filters.push({key:key,op:op,compare:compare});return this}where(key,op,compare){return this.filter(key,op,compare)}take(n){this[_private].take=n;return this}skip(n){this[_private].skip=n;return this}sort(key,ascending=true){if(typeof key!=="string"){throw`key must be a string`}this[_private].order.push({key:key,ascending:ascending});return this}order(key,ascending=true){return this.sort(key,ascending)}get(optionsOrCallback=undefined,callback=undefined){callback=typeof optionsOrCallback==="function"?optionsOrCallback:typeof callback==="function"?callback:undefined;const options=typeof optionsOrCallback==="object"?optionsOrCallback:new QueryDataRetrievalOptions({snapshots:true});if(typeof options.snapshots==="undefined"){options.snapshots=true}options.eventHandler=ev=>{if(!this._events||!this._events[ev.name]){return false}const listeners=this._events[ev.name];if(typeof listeners!=="object"||listeners.length===0){return false}if(["add","change","remove"].includes(ev.name)){const ref=new DataReference(this.ref.db,ev.path);const eventData={name:ev.name};if(options.snapshots&&ev.name!=="remove"){const val=db.types.deserialize(ev.path,ev.value);eventData.snapshot=new DataSnapshot(ref,val,false)}else{eventData.ref=ref}ev=eventData}listeners.forEach(callback=>{try{callback(ev)}catch(e){}})};options.monitor={add:false,change:false,remove:false};if(this._events){if(this._events["add"]&&this._events["add"].length>0){options.monitor.add=true}if(this._events["change"]&&this._events["change"].length>0){options.monitor.change=true}if(this._events["remove"]&&this._events["remove"].length>0){options.monitor.remove=true}}const db=this.ref.db;return db.api.query(this.ref.path,this[_private],options).catch(err=>{throw new Error(err)}).then(results=>{results.forEach((result,index)=>{if(options.snapshots){const val=db.types.deserialize(result.path,result.val);results[index]=new DataSnapshot(db.ref(result.path),val)}else{results[index]=db.ref(result)}});if(options.snapshots){return DataSnapshotsArray.from(results)}else{return DataReferencesArray.from(results)}}).then(results=>{callback&&callback(results);return results})}getRefs(callback=undefined){return this.get({snapshots:false},callback)}remove(callback){return this.get({snapshots:false}).then(refs=>{const promises=[];return Promise.all(refs.map(ref=>ref.remove())).then(()=>{callback&&callback()})})}on(event,callback){if(!this._events){this._events={}}if(!this._events[event]){this._events[event]=[]}this._events[event].push(callback);return this}off(event,callback){if(!this._events){return this}if(typeof event==="undefined"){this._events={};return this}if(!this._events[event]){return this}if(typeof callback==="undefined"){delete this._events[event];return this}const index=!this._events[event].indexOf(callback);if(!~index){return this}this._events[event].splice(index,1);return this}}class DataSnapshotsArray extends Array{static from(snaps){const arr=new DataSnapshotsArray(snaps.length);snaps.forEach((snap,i)=>arr[i]=snap);return arr}getValues(){return this.map(snap=>snap.val())}}class DataReferencesArray extends Array{static from(refs){const arr=new DataReferencesArray(refs.length);refs.forEach((ref,i)=>arr[i]=ref);return arr}getPaths(){return this.map(ref=>ref.path)}}module.exports={DataReference:DataReference,DataReferenceQuery:DataReferenceQuery,DataRetrievalOptions:DataRetrievalOptions,QueryDataRetrievalOptions:QueryDataRetrievalOptions}},{"./data-snapshot":8,"./debug":9,"./id":10,"./path-info":12,"./subscription":14}],8:[function(require,module,exports){const{DataReference:DataReference}=require("./data-reference");const{getPathKeys:getPathKeys}=require("./path-info");const getChild=(snapshot,path)=>{if(!snapshot.exists()){return null}let child=snapshot.val();getPathKeys(path).every(key=>{child=child[key];return typeof child!=="undefined"});return child||null};const getChildren=snapshot=>{if(!snapshot.exists()){return[]}let value=snapshot.val();if(value instanceof Array){return new Array(value.length).map((v,i)=>i)}if(typeof value==="object"){return Object.keys(value)}return[]};class DataSnapshot{constructor(ref,value,isRemoved=false){this.ref=ref;this.val=()=>{return value};this.exists=()=>{if(isRemoved){return false}return value!==null&&typeof value!=="undefined"}}child(path){let child=getChild(this,path);return new DataSnapshot(this.ref.child(path),child)}hasChild(path){return getChild(this,path)!==null}hasChildren(){return getChildren(this).length>0}numChildren(){return getChildren(this).length}forEach(callback){const value=this.val();return getChildren(this).every((key,i)=>{const snap=new DataSnapshot(this.ref.child(key),value[key]);return callback(snap)})}get key(){return this.ref.key}}module.exports={DataSnapshot:DataSnapshot}},{"./data-reference":7,"./path-info":12}],9:[function(require,module,exports){class DebugLogger{constructor(level="log",prefix=""){this.prefix=prefix;this.setLevel(level)}setLevel(level){const prefix=this.prefix?this.prefix:"";this.level=level;this.verbose=["verbose"].includes(level)?console.log.bind(console,prefix):()=>{};this.log=["verbose","log"].includes(level)?console.log.bind(console,prefix):()=>{};this.warn=["verbose","log","warn"].includes(level)?console.warn.bind(console,prefix):()=>{};this.error=["verbose","log","warn","error"].includes(level)?console.error.bind(console,prefix):()=>{};this.write=console.log.bind(console)}}module.exports=DebugLogger},{}],10:[function(require,module,exports){const cuid=require("cuid");class ID{static generate(){return cuid().slice(1)}}module.exports={ID:ID}},{cuid:1}],11:[function(require,module,exports){const{AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings}=require("./acebase-base");const{Api:Api}=require("./api");const{DataReference:DataReference,DataReferenceQuery:DataReferenceQuery,DataRetrievalOptions:DataRetrievalOptions,QueryDataRetrievalOptions:QueryDataRetrievalOptions}=require("./data-reference");const{DataSnapshot:DataSnapshot}=require("./data-snapshot");const DebugLogger=require("./debug");const{ID:ID}=require("./id");const{PathReference:PathReference}=require("./path-reference");const{EventStream:EventStream,EventPublisher:EventPublisher,EventSubscription:EventSubscription}=require("./subscription");const Transport=require("./transport");const{TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions}=require("./type-mappings");const Utils=require("./utils");const{PathInfo:PathInfo}=require("./path-info");const ascii85=require("./ascii85");module.exports={AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings,Api:Api,DataReference:DataReference,DataReferenceQuery:DataReferenceQuery,DataRetrievalOptions:DataRetrievalOptions,QueryDataRetrievalOptions:QueryDataRetrievalOptions,DataSnapshot:DataSnapshot,DebugLogger:DebugLogger,ID:ID,PathReference:PathReference,EventStream:EventStream,EventPublisher:EventPublisher,EventSubscription:EventSubscription,Transport:Transport,TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions,Utils:Utils,PathInfo:PathInfo,ascii85:ascii85}},{"./acebase-base":4,"./api":5,"./ascii85":6,"./data-reference":7,"./data-snapshot":8,"./debug":9,"./id":10,"./path-info":12,"./path-reference":13,"./subscription":14,"./transport":15,"./type-mappings":16,"./utils":17}],12:[function(require,module,exports){function getPathKeys(path){if(path.length===0){return[]}let keys=path.replace(/\[/g,"/[").split("/");keys.forEach((key,index)=>{if(key.startsWith("[")){keys[index]=parseInt(key.substr(1,key.length-2))}});return keys}function getPathInfo(path){if(path.length===0){return{parent:null,key:""}}const i=Math.max(path.lastIndexOf("/"),path.lastIndexOf("["));const parentPath=i<0?"":path.substr(0,i);let key=i<0?path:path.substr(i);if(key.startsWith("[")){key=parseInt(key.substr(1,key.length-2))}else if(key.startsWith("/")){key=key.substr(1)}if(parentPath===path){parentPath=null}return{parent:parentPath,key:key}}function getChildPath(path,key){if(path.length===0){if(typeof key==="number"){throw new TypeError("Cannot add array index to root path!")}return key}if(typeof key==="number"){return`${path}[${key}]`}return`${path}/${key}`}class PathInfo{static get(path){return new PathInfo(path)}static getChildPath(path,childKey){return getChildPath(path,childKey)}static getPathKeys(path){return getPathKeys(path)}constructor(path){this.path=path}get key(){return getPathInfo(this.path).key}get parentPath(){return getPathInfo(this.path).parent}childPath(childKey){return getChildPath(`${this.path}`,childKey)}get pathKeys(){return getPathKeys(this.path)}static extractVariables(varPath,fullPath){if(!varPath.includes("*")&&!varPath.includes("$")){return[]}const keys=getPathKeys(varPath);const pathKeys=getPathKeys(fullPath);let count=0;const variables={get length(){return count}};keys.forEach((key,index)=>{const pathKey=pathKeys[index];if(key==="*"){variables[count++]=pathKey}else if(typeof key==="string"&&key[0]==="$"){variables[count++]=pathKey;variables[key]=pathKey;const varName=key.slice(1);if(typeof variables[varName]==="undefined"){variables[varName]=pathKey}}});return variables}static fillVariables(varPath,fullPath){if(varPath.indexOf("*")<0&&varPath.indexOf("$")<0){return varPath}const keys=getPathKeys(varPath);const pathKeys=getPathKeys(fullPath);let merged=keys.map((key,index)=>{if(key===pathKeys[index]||index>=pathKeys.length){return key}else if(typeof key==="string"&&(key==="*"||key[0]==="$")){return pathKeys[index]}else{throw new Error(`Path "${fullPath}" cannot be used to fill variables of path "${this.path}" because they do not match`)}});let mergedPath="";merged.forEach(key=>{if(typeof key==="number"){mergedPath+=`[${key}]`}else{if(mergedPath.length>0){mergedPath+="/"}mergedPath+=key}});return mergedPath}static fillVariables2(varPath,vars){if(typeof vars!=="object"||Object.keys(vars).length===0){return varPath}let pathKeys=getPathKeys(varPath);let n=0;const targetPath=pathKeys.reduce((path,key)=>{if(key==="*"||key.startsWith("$")){key=vars[n++]}if(typeof key==="number"){return`${path}[${key}]`}else{return`${path}/${key}`}},"");return targetPath}equals(otherPath){if(this.path===otherPath){return true}const keys=getPathKeys(this.path);const otherKeys=getPathKeys(otherPath);if(keys.length!==otherKeys.length){return false}return keys.every((key,index)=>{const otherKey=otherKeys[index];return otherKey===key||typeof otherKey==="string"&&(otherKey==="*"||otherKey[0]==="$")||typeof key==="string"&&(key==="*"||key[0]==="$")})}isAncestorOf(descendantPath){if(descendantPath===""||this.path===descendantPath){return false}if(this.path===""){return true}const ancestorKeys=getPathKeys(this.path);const descendantKeys=getPathKeys(descendantPath);if(ancestorKeys.length>=descendantKeys.length){return false}return ancestorKeys.every((key,index)=>{const otherKey=descendantKeys[index];return otherKey===key||typeof otherKey==="string"&&(otherKey==="*"||otherKey[0]==="$")||typeof key==="string"&&(key==="*"||key[0]==="$")})}isDescendantOf(ancestorPath){if(this.path===""||this.path===ancestorPath){return false}if(ancestorPath===""){return true}const ancestorKeys=getPathKeys(ancestorPath);const descendantKeys=getPathKeys(this.path);if(ancestorKeys.length>=descendantKeys.length){return false}return ancestorKeys.every((key,index)=>{const otherKey=descendantKeys[index];return otherKey===key||typeof otherKey==="string"&&(otherKey==="*"||otherKey[0]==="$")||typeof key==="string"&&(key==="*"||key[0]==="$")})}isChildOf(otherPath){if(this.path===""){return false}const parentInfo=PathInfo.get(this.parentPath);return parentInfo.equals(otherPath)}isParentOf(otherPath){if(otherPath===""){return false}const parentInfo=PathInfo.get(PathInfo.get(otherPath).parentPath);return parentInfo.equals(this.path)}}module.exports={getPathInfo:getPathInfo,getChildPath:getChildPath,getPathKeys:getPathKeys,PathInfo:PathInfo}},{}],13:[function(require,module,exports){class PathReference{constructor(path){this.path=path}}module.exports={PathReference:PathReference}},{}],14:[function(require,module,exports){class EventSubscription{constructor(stop){this.stop=stop;this._internal={state:"init",cancelReason:undefined,activatePromises:[]}}activated(callback=undefined){if(callback){this._internal.activatePromises.push({callback:callback});if(this._internal.state==="active"){callback(true)}else if(this._internal.state==="canceled"){callback(false,this._internal.cancelReason)}}return new Promise((resolve,reject)=>{if(this._internal.state==="active"){return resolve()}else if(this._internal.state==="canceled"&&!callback){return reject(new Error(this._internal.cancelReason))}this._internal.activatePromises.push({resolve:resolve,reject:callback?()=>{}:reject})})}_setActivationState(activated,cancelReason){this._internal.cancelReason=cancelReason;this._internal.state=activated?"active":"canceled";while(this._internal.activatePromises.length>0){const p=this._internal.activatePromises.shift();if(activated){p.callback&&p.callback(true);p.resolve&&p.resolve()}else{p.callback&&p.callback(false,cancelReason);p.reject&&p.reject(cancelReason)}}}}class EventPublisher{constructor(publish,start,cancel){this.publish=publish;this.start=start;this.cancel=cancel}}class EventStream{constructor(eventPublisherCallback){const subscribers=[];let noMoreSubscribersCallback;let activationState;const _stoppedState="stopped (no more subscribers)";this.subscribe=(callback,activationCallback)=>{if(typeof callback!=="function"){throw new TypeError("callback must be a function")}else if(activationState===_stoppedState){throw new Error("stream can't be used anymore because all subscribers were stopped")}const sub={callback:callback,activationCallback:function(activated,cancelReason){activationCallback&&activationCallback(activated,cancelReason);this.subscription._setActivationState(activated,cancelReason)},subscription:new EventSubscription((function stop(){subscribers.splice(subscribers.indexOf(this),1);checkActiveSubscribers()}))};subscribers.push(sub);if(typeof activationState!=="undefined"){if(activationState===true){activationCallback&&activationCallback(true);sub.subscription._setActivationState(true)}else if(typeof activationState==="string"){activationCallback&&activationCallback(false,activationState);sub.subscription._setActivationState(false,activationState)}}return sub.subscription};const checkActiveSubscribers=()=>{if(subscribers.length===0){noMoreSubscribersCallback&&noMoreSubscribersCallback();activationState=_stoppedState}};this.unsubscribe=(callback=undefined)=>{const remove=callback?subscribers.filter(sub=>sub.callback===callback):subscribers;remove.forEach(sub=>{const i=subscribers.indexOf(sub);subscribers.splice(i,1)});checkActiveSubscribers()};this.stop=()=>{subscribers.splice(0);checkActiveSubscribers()};const publish=val=>{subscribers.forEach(sub=>{try{sub.callback(val)}catch(err){debug.error(`Error running subscriber callback: ${err.message}`)}});return subscribers.length>0};const start=allSubscriptionsStoppedCallback=>{activationState=true;noMoreSubscribersCallback=allSubscriptionsStoppedCallback;subscribers.forEach(sub=>{sub.activationCallback&&sub.activationCallback(true)})};const cancel=reason=>{activationState=reason;subscribers.forEach(sub=>{sub.activationCallback&&sub.activationCallback(false,reason||new Error("unknown reason"))});subscribers.splice()};const publisher=new EventPublisher(publish,start,cancel);eventPublisherCallback(publisher)}}module.exports={EventStream:EventStream,EventPublisher:EventPublisher,EventSubscription:EventSubscription}},{}],15:[function(require,module,exports){const{PathReference:PathReference}=require("./path-reference");const{cloneObject:cloneObject}=require("./utils");const ascii85=require("./ascii85");module.exports={deserialize(data){if(data.map===null||typeof data.map==="undefined"){return data.val}const deserializeValue=(type,val)=>{if(type==="date"){return new Date(val)}else if(type==="binary"){return ascii85.decode(val)}else if(type==="reference"){return new PathReference(val)}else if(type==="regexp"){return new RegExp(val.pattern,val.flags)}return val};if(typeof data.map==="string"){return deserializeValue(data.map,data.val)}Object.keys(data.map).forEach(path=>{const type=data.map[path];const keys=path.replace(/\[/g,"/[").split("/");keys.forEach((key,index)=>{if(key.startsWith("[")){keys[index]=parseInt(key.substr(1,key.length-2))}});let parent=data;let key="val";let val=data.val;keys.forEach(k=>{key=k;parent=val;val=val[key]});parent[key]=deserializeValue(type,val)});return data.val},serialize(obj){if(obj===null||typeof obj!=="object"||obj instanceof Date||obj instanceof ArrayBuffer||obj instanceof PathReference){const ser=this.serialize({value:obj});return{map:ser.map.value,val:ser.val.value}}obj=cloneObject(obj);const process=(obj,mappings,prefix)=>{Object.keys(obj).forEach(key=>{const val=obj[key];const path=prefix.length===0?key:`${prefix}/${key}`;if(val instanceof Date){obj[key]=val.toISOString();mappings[path]="date"}else if(val instanceof ArrayBuffer){obj[key]=ascii85.encode(val);mappings[path]="binary"}else if(val instanceof PathReference){obj[key]=val.path;mappings[path]="reference"}else if(val instanceof RegExp){obj[key]={pattern:val.source,flags:val.flags};mappings[path]="regexp"}else if(typeof val==="object"&&val!==null){process(val,mappings,path)}})};const mappings={};process(obj,mappings,"");return{map:mappings,val:obj}}}},{"./ascii85":6,"./path-reference":13,"./utils":17}],16:[function(require,module,exports){const{cloneObject:cloneObject}=require("./utils");const{PathInfo:PathInfo}=require("./path-info");const{AceBaseBase:AceBaseBase}=require("./acebase-base");const{DataReference:DataReference}=require("./data-reference");const{DataSnapshot:DataSnapshot}=require("./data-snapshot");const get=(mappings,path)=>{path=path.replace(/^\/|\/$/g,"");const keys=PathInfo.getPathKeys(path);const mappedPath=Object.keys(mappings).find(mpath=>{const mkeys=PathInfo.getPathKeys(mpath);if(mkeys.length!==keys.length){return false}return mkeys.every((mkey,index)=>{if(mkey==="*"||mkey[0]==="$"){return true}return mkey===keys[index]})});const mapping=mappings[mappedPath];return mapping};const map=(mappings,path)=>{const targetPath=PathInfo.get(path).parentPath;if(targetPath===null){return}return get(mappings,targetPath)};const mapDeep=(mappings,entryPath)=>{entryPath=entryPath.replace(/^\/|\/$/g,"");const pathInfo=PathInfo.get(entryPath);const startPath=pathInfo.parentPath;const keys=startPath?PathInfo.getPathKeys(startPath):[];const matches=Object.keys(mappings).reduce((m,mpath)=>{const mkeys=PathInfo.getPathKeys(mpath);if(mkeys.length{if(index>=keys.length){return false}else if(mkey==="*"||mkey[0]==="$"||mkey===keys[index]){return true}else{isMatch=false;return false}})}if(isMatch){const mapping=mappings[mpath];m.push({path:mpath,type:mapping})}return m},[]);return matches};const process=(db,mappings,path,obj,action)=>{if(obj===null||typeof obj!=="object"){return obj}const keys=PathInfo.getPathKeys(path);const m=mapDeep(mappings,path);const changes=[];m.sort((a,b)=>PathInfo.getPathKeys(a.path).length>PathInfo.getPathKeys(b.path).length?-1:1);m.forEach(mapping=>{const mkeys=PathInfo.getPathKeys(mapping.path);mkeys.push("*");const mTrailKeys=mkeys.slice(keys.length);if(mTrailKeys.length===0){const vars=PathInfo.extractVariables(mapping.path,path);const ref=new DataReference(db,path,vars);if(action==="serialize"){obj=mapping.type.serialize(obj,ref)}else if(action==="deserialize"){const snap=new DataSnapshot(ref,obj);obj=mapping.type.deserialize(snap)}return}const process=(parentPath,parent,keys)=>{if(obj===null||typeof obj!=="object"){return obj}const key=keys[0];let children=[];if(key==="*"||key[0]==="$"){if(parent instanceof Array){children=parent.map((val,index)=>({key:index,val:val}))}else{children=Object.keys(parent).map(k=>({key:k,val:parent[k]}))}}else{const child=parent[key];if(typeof child==="object"){children.push({key:key,val:child})}}children.forEach(child=>{const childPath=PathInfo.getChildPath(parentPath,child.key);const vars=PathInfo.extractVariables(mapping.path,childPath);const ref=new DataReference(db,childPath,vars);if(keys.length===1){if(action==="serialize"){changes.push({parent:parent,key:child.key,original:parent[child.key]});parent[child.key]=mapping.type.serialize(child.val,ref)}else if(action==="deserialize"){const snap=new DataSnapshot(ref,child.val);parent[child.key]=mapping.type.deserialize(snap)}}else{process(childPath,child.val,keys.slice(1))}})};process(path,obj,mTrailKeys)});if(action==="serialize"){obj=cloneObject(obj);if(changes.length>0){changes.forEach(change=>{change.parent[change.key]=change.original})}}return obj};class TypeMappingOptions{constructor(options){if(!options){options={}}this.serializer=options.serializer;this.creator=options.creator}}const _mappings=Symbol("mappings");class TypeMappings{constructor(db){this.db=db;this[_mappings]={}}get mappings(){return this[_mappings]}map(path){return map(this[_mappings],path)}bind(path,type,options={}){if(typeof path!=="string"){throw new TypeError("path must be a string")}if(typeof type!=="function"){throw new TypeError("constructor must be a function")}if(typeof options.serializer==="undefined"){if(typeof type.prototype.serialize==="function"){options.serializer=type.prototype.serialize}}if(typeof options.serializer==="string"){if(typeof type.prototype[options.serializer]==="function"){options.serializer=type.prototype[options.serializer]}else{throw new TypeError(`${type.name}.prototype.${options.serializer} is not a function, cannot use it as serializer`)}}else if(typeof options.serializer!=="function"){throw new TypeError(`serializer for class ${type.name} must be a function, or the name of a prototype method`)}if(typeof options.creator==="undefined"){if(typeof type.create==="function"){options.creator=type.create}}else if(typeof options.creator==="string"){if(typeof type[options.creator]==="function"){options.creator=type[options.creator]}else{throw new TypeError(`${type.name}.${options.creator} is not a function, cannot use it as creator`)}}else if(typeof options.creator!=="function"){throw new TypeError(`creator for class ${type.name} must be a function, or the name of a static method`)}path=path.replace(/^\/|\/$/g,"");this[_mappings][path]={db:this.db,type:type,creator:options.creator,serializer:options.serializer,deserialize(snap){let obj;if(this.creator){obj=this.creator.call(this.type,snap)}else{obj=new this.type(snap)}return obj},serialize(obj,ref){if(this.serializer){obj=this.serializer.call(obj,ref,obj)}return obj}}}serialize(path,obj){return process(this.db,this[_mappings],path,obj,"serialize")}deserialize(path,obj){return process(this.db,this[_mappings],path,obj,"deserialize")}}module.exports={TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions}},{"./acebase-base":4,"./data-reference":7,"./data-snapshot":8,"./path-info":12,"./utils":17}],17:[function(require,module,exports){(function(Buffer){const{PathReference:PathReference}=require("./path-reference");function numberToBytes(number){const bytes=new Uint8Array(8);const view=new DataView(bytes.buffer);view.setFloat64(0,number);return new Array(...bytes)}function bytesToNumber(bytes){if(bytes.length<8){throw new TypeError("must be 8 bytes")}const bin=new Uint8Array(bytes);const view=new DataView(bin.buffer);const nr=view.getFloat64(0);return nr}function encodeString(str){if(typeof TextEncoder!=="undefined"){const encoder=new TextEncoder;return encoder.encode(str)}else if(typeof Buffer==="function"){const buf=Buffer.from(str,"utf-8");return new Uint8Array(buf.buffer,buf.byteOffset,buf.byteLength)}else{let arr=[];for(let i=0;i128){if((code&55296)===55296){const nextCode=str.charCodeAt(i+1);if((nextCode&56320)!==56320){throw new Error("follow-up utf-16 character does not start with 0xDC00")}i++;const p1=code&1023;const p2=nextCode&1023;code=65536|p1<<10|p2}if(code<2048){const b1=192|code>>6&31;const b2=128|code&63;arr.push(b1,b2)}else if(code<65536){const b1=224|code>>12&15;const b2=128|code>>6&63;const b3=128|code&63;arr.push(b1,b2,b3)}else if(code<2097152){const b1=240|code>>18&7;const b2=128|code>>12&63;const b3=128|code>>6&63;const b4=128|code&63;arr.push(b1,b2,b3,b4)}else{throw new Error(`Cannot convert character ${str.charAt(i)} (code ${code}) to utf-8`)}}else{arr.push(code<128?code:63)}}return new Uint8Array(arr)}}function decodeString(buffer){if(typeof TextDecoder!=="undefined"){const decoder=new TextDecoder;if(buffer instanceof Uint8Array){return decoder.decode(buffer)}const buf=Uint8Array.from(buffer);return decoder.decode(buf)}else if(typeof Buffer==="function"){if(buffer instanceof Buffer){return buffer.toString("utf-8")}else if(buffer instanceof Array){const typedArray=Uint8Array.from(buffer);const buf=Buffer.from(typedArray.buffer,typedArray.byteOffset,typedArray.byteOffset+typedArray.byteLength);return buf.toString("utf-8")}else if("buffer"in buffer&&buffer["buffer"]instanceof ArrayBuffer){const buf=Buffer.from(buffer["buffer"],buffer.byteOffset,buffer.byteOffset+buffer.byteLength);return buf.toString("utf-8")}else{throw new Error(`Unsupported buffer argument`)}}else{if(!(buffer instanceof Uint8Array)&&"buffer"in buffer&&buffer["buffer"]instanceof ArrayBuffer){buffer=new Uint8Array(buffer["buffer"],buffer.byteOffset,buffer.byteLength)}if(buffer instanceof Buffer||buffer instanceof Array||buffer instanceof Uint8Array){let str="";for(let i=0;i128){if((code&240)===240){const b1=code,b2=buffer[i+1],b3=buffer[i+2],b4=buffer[i+3];code=(b1&7)<<18|(b2&63)<<12|(b3&63)<<6|b4&63;i+=3}else if((code&224)===224){const b1=code,b2=buffer[i+1],b3=buffer[i+2];code=(b1&15)<<12|(b2&63)<<6|b3&63;i+=2}else if((code&192)===192){const b1=code,b2=buffer[i+1];code=(b1&31)<<6|b2&63;i++}else{throw new Error(`invalid utf-8 data`)}}if(code>=65536){code^=65536;const p1=55296|code>>10;const p2=56320|code&1023;str+=String.fromCharCode(p1);str+=String.fromCharCode(p2)}else{str+=String.fromCharCode(code)}}return str}else{throw new Error(`Unsupported buffer argument`)}}}function concatTypedArrays(a,b){const c=new a.constructor(a.length+b.length);c.set(a);c.set(b,a.length);return c}function cloneObject(original,stack){const{DataSnapshot:DataSnapshot}=require("./data-snapshot");if(original instanceof DataSnapshot){throw new TypeError(`Object to clone is a DataSnapshot (path "${original.ref.path}")`)}const checkAndFixTypedArray=obj=>{if(obj!==null&&typeof obj==="object"&&typeof obj.constructor==="function"&&typeof obj.constructor.name==="string"&&["Buffer","Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","BigUint64Array","BigInt64Array"].includes(obj.constructor.name)){obj=obj.buffer.slice(obj.byteOffset,obj.byteOffset+obj.byteLength)}return obj};original=checkAndFixTypedArray(original);if(typeof original!=="object"||original===null||original instanceof Date||original instanceof ArrayBuffer||original instanceof PathReference||original instanceof RegExp){return original}const cloneValue=val=>{if(stack.indexOf(val)>=0){throw new ReferenceError(`object contains a circular reference`)}val=checkAndFixTypedArray(val);if(val===null||val instanceof Date||val instanceof ArrayBuffer||val instanceof PathReference||val instanceof RegExp){return val}else if(val instanceof Array){stack.push(val);val=val.map(item=>cloneValue(item));stack.pop();return val}else if(typeof val==="object"){stack.push(val);val=cloneObject(val,stack);stack.pop();return val}else{return val}};if(typeof stack==="undefined"){stack=[original]}const clone={};Object.keys(original).forEach(key=>{let val=original[key];if(typeof val==="function"){return}clone[key]=cloneValue(val)});return clone}function compareValues(oldVal,newVal){const voids=[undefined,null];if(oldVal===newVal){return"identical"}else if(voids.indexOf(oldVal)>=0&&voids.indexOf(newVal)<0){return"added"}else if(voids.indexOf(oldVal)<0&&voids.indexOf(newVal)>=0){return"removed"}else if(typeof oldVal!==typeof newVal){return"changed"}else if(typeof oldVal==="object"){const isArray=oldVal instanceof Array;const oldKeys=isArray?Object.keys(oldVal).map(v=>parseInt(v)):Object.keys(oldVal);const newKeys=isArray?Object.keys(newVal).map(v=>parseInt(v)):Object.keys(newVal);const removedKeys=oldKeys.filter(key=>newKeys.indexOf(key)<0);const addedKeys=newKeys.filter(key=>oldKeys.indexOf(key)<0);const changedKeys=newKeys.reduce((changed,key)=>{if(oldKeys.indexOf(key)>=0){const val1=oldVal[key];const val2=newVal[key];const c=compareValues(val1,val2);if(c!=="identical"){changed.push({key:key,change:c})}}return changed},[]);if(addedKeys.length===0&&removedKeys.length===0&&changedKeys.length===0){return"identical"}else{return{added:addedKeys,removed:removedKeys,changed:changedKeys}}}else if(oldVal!==newVal){return"changed"}return"identical"}const getChildValues=(childKey,oldValue,newValue)=>{oldValue=oldValue===null?null:oldValue[childKey];if(typeof oldValue==="undefined"){oldValue=null}newValue=newValue===null?null:newValue[childKey];if(typeof newValue==="undefined"){newValue=null}return{oldValue:oldValue,newValue:newValue}};module.exports={numberToBytes:numberToBytes,bytesToNumber:bytesToNumber,concatTypedArrays:concatTypedArrays,cloneObject:cloneObject,compareValues:compareValues,getChildValues:getChildValues,encodeString:encodeString,decodeString:decodeString}}).call(this,require("buffer").Buffer)},{"./data-snapshot":8,"./path-reference":13,buffer:39}],18:[function(require,module,exports){var colors={};module["exports"]=colors;colors.themes={};var util=require("util");var ansiStyles=colors.styles=require("./styles");var defineProps=Object.defineProperties;var newLineRegex=new RegExp(/[\r\n]+/g);colors.supportsColor=require("./system/supports-colors").supportsColor;if(typeof colors.enabled==="undefined"){colors.enabled=colors.supportsColor()!==false}colors.enable=function(){colors.enabled=true};colors.disable=function(){colors.enabled=false};colors.stripColors=colors.strip=function(str){return(""+str).replace(/\x1B\[\d+m/g,"")};var stylize=colors.stylize=function stylize(str,style){if(!colors.enabled){return str+""}return ansiStyles[style].open+str+ansiStyles[style].close};var matchOperatorsRe=/[|\\{}()[\]^$+*?.]/g;var escapeStringRegexp=function(str){if(typeof str!=="string"){throw new TypeError("Expected a string")}return str.replace(matchOperatorsRe,"\\$&")};function build(_styles){var builder=function builder(){return applyStyle.apply(builder,arguments)};builder._styles=_styles;builder.__proto__=proto;return builder}var styles=function(){var ret={};ansiStyles.grey=ansiStyles.gray;Object.keys(ansiStyles).forEach((function(key){ansiStyles[key].closeRe=new RegExp(escapeStringRegexp(ansiStyles[key].close),"g");ret[key]={get:function(){return build(this._styles.concat(key))}}}));return ret}();var proto=defineProps((function colors(){}),styles);function applyStyle(){var args=Array.prototype.slice.call(arguments);var str=args.map((function(arg){if(arg!=undefined&&arg.constructor===String){return arg}else{return util.inspect(arg)}})).join(" ");if(!colors.enabled||!str){return str}var newLinesPresent=str.indexOf("\n")!=-1;var nestedStyles=this._styles;var i=nestedStyles.length;while(i--){var code=ansiStyles[nestedStyles[i]];str=code.open+str.replace(code.closeRe,code.open)+code.close;if(newLinesPresent){str=str.replace(newLineRegex,(function(match){return code.close+match+code.open}))}}return str}colors.setTheme=function(theme){if(typeof theme==="string"){console.log("colors.setTheme now only accepts an object, not a string. "+"If you are trying to set a theme from a file, it is now your (the "+"caller's) responsibility to require the file. The old syntax "+"looked like colors.setTheme(__dirname + "+"'/../themes/generic-logging.js'); The new syntax looks like "+"colors.setTheme(require(__dirname + "+"'/../themes/generic-logging.js'));");return}for(var style in theme){(function(style){colors[style]=function(str){if(typeof theme[style]==="object"){var out=str;for(var i in theme[style]){out=colors[theme[style][i]](out)}return out}return colors[theme[style]](str)}})(style)}};function init(){var ret={};Object.keys(styles).forEach((function(name){ret[name]={get:function(){return build([name])}}}));return ret}var sequencer=function sequencer(map,str){var exploded=str.split("");exploded=exploded.map(map);return exploded.join("")};colors.trap=require("./custom/trap");colors.zalgo=require("./custom/zalgo");colors.maps={};colors.maps.america=require("./maps/america")(colors);colors.maps.zebra=require("./maps/zebra")(colors);colors.maps.rainbow=require("./maps/rainbow")(colors);colors.maps.random=require("./maps/random")(colors);for(var map in colors.maps){(function(map){colors[map]=function(str){return sequencer(colors.maps[map],str)}})(map)}defineProps(colors,init())},{"./custom/trap":19,"./custom/zalgo":20,"./maps/america":23,"./maps/rainbow":24,"./maps/random":25,"./maps/zebra":26,"./styles":27,"./system/supports-colors":29,util:45}],19:[function(require,module,exports){module["exports"]=function runTheTrap(text,options){var result="";text=text||"Run the trap, drop the bass";text=text.split("");var trap={a:["@","Ą","Ⱥ","Ʌ","Δ","Λ","Д"],b:["ß","Ɓ","Ƀ","ɮ","β","฿"],c:["©","Ȼ","Ͼ"],d:["Ð","Ɗ","Ԁ","ԁ","Ԃ","ԃ"],e:["Ë","ĕ","Ǝ","ɘ","Σ","ξ","Ҽ","੬"],f:["Ӻ"],g:["ɢ"],h:["Ħ","ƕ","Ң","Һ","Ӈ","Ԋ"],i:["༏"],j:["Ĵ"],k:["ĸ","Ҡ","Ӄ","Ԟ"],l:["Ĺ"],m:["ʍ","Ӎ","ӎ","Ԡ","ԡ","൩"],n:["Ñ","ŋ","Ɲ","Ͷ","Π","Ҋ"],o:["Ø","õ","ø","Ǿ","ʘ","Ѻ","ם","۝","๏"],p:["Ƿ","Ҏ"],q:["্"],r:["®","Ʀ","Ȑ","Ɍ","ʀ","Я"],s:["§","Ϟ","ϟ","Ϩ"],t:["Ł","Ŧ","ͳ"],u:["Ʊ","Ս"],v:["ט"],w:["Ш","Ѡ","Ѽ","൰"],x:["Ҳ","Ӿ","Ӽ","ӽ"],y:["¥","Ұ","Ӌ"],z:["Ƶ","ɀ"]};text.forEach((function(c){c=c.toLowerCase();var chars=trap[c]||[" "];var rand=Math.floor(Math.random()*chars.length);if(typeof trap[c]!=="undefined"){result+=trap[c][rand]}else{result+=c}}));return result}},{}],20:[function(require,module,exports){module["exports"]=function zalgo(text,options){text=text||" he is here ";var soul={up:["̍","̎","̄","̅","̿","̑","̆","̐","͒","͗","͑","̇","̈","̊","͂","̓","̈","͊","͋","͌","̃","̂","̌","͐","̀","́","̋","̏","̒","̓","̔","̽","̉","ͣ","ͤ","ͥ","ͦ","ͧ","ͨ","ͩ","ͪ","ͫ","ͬ","ͭ","ͮ","ͯ","̾","͛","͆","̚"],down:["̖","̗","̘","̙","̜","̝","̞","̟","̠","̤","̥","̦","̩","̪","̫","̬","̭","̮","̯","̰","̱","̲","̳","̹","̺","̻","̼","ͅ","͇","͈","͉","͍","͎","͓","͔","͕","͖","͙","͚","̣"],mid:["̕","̛","̀","́","͘","̡","̢","̧","̨","̴","̵","̶","͜","͝","͞","͟","͠","͢","̸","̷","͡"," ҉"]};var all=[].concat(soul.up,soul.down,soul.mid);function randomNumber(range){var r=Math.floor(Math.random()*range);return r}function isChar(character){var bool=false;all.filter((function(i){bool=i===character}));return bool}function heComes(text,options){var result="";var counts;var l;options=options||{};options["up"]=typeof options["up"]!=="undefined"?options["up"]:true;options["mid"]=typeof options["mid"]!=="undefined"?options["mid"]:true;options["down"]=typeof options["down"]!=="undefined"?options["down"]:true;options["size"]=typeof options["size"]!=="undefined"?options["size"]:"maxi";text=text.split("");for(l in text){if(isChar(l)){continue}result=result+text[l];counts={up:0,down:0,mid:0};switch(options.size){case"mini":counts.up=randomNumber(8);counts.mid=randomNumber(2);counts.down=randomNumber(8);break;case"maxi":counts.up=randomNumber(16)+3;counts.mid=randomNumber(4)+1;counts.down=randomNumber(64)+3;break;default:counts.up=randomNumber(8)+1;counts.mid=randomNumber(6)/2;counts.down=randomNumber(8)+1;break}var arr=["up","mid","down"];for(var d in arr){var index=arr[d];for(var i=0;i<=counts[index];i++){if(options[index]){result=result+soul[index][randomNumber(soul[index].length)]}}}}return result}return heComes(text,options)}},{}],21:[function(require,module,exports){var colors=require("./colors");module["exports"]=function(){var addProperty=function(color,func){String.prototype.__defineGetter__(color,func)};addProperty("strip",(function(){return colors.strip(this)}));addProperty("stripColors",(function(){return colors.strip(this)}));addProperty("trap",(function(){return colors.trap(this)}));addProperty("zalgo",(function(){return colors.zalgo(this)}));addProperty("zebra",(function(){return colors.zebra(this)}));addProperty("rainbow",(function(){return colors.rainbow(this)}));addProperty("random",(function(){return colors.random(this)}));addProperty("america",(function(){return colors.america(this)}));var x=Object.keys(colors.styles);x.forEach((function(style){addProperty(style,(function(){return colors.stylize(this,style)}))}));function applyTheme(theme){var stringPrototypeBlacklist=["__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__","charAt","constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf","charCodeAt","indexOf","lastIndexOf","length","localeCompare","match","repeat","replace","search","slice","split","substring","toLocaleLowerCase","toLocaleUpperCase","toLowerCase","toUpperCase","trim","trimLeft","trimRight"];Object.keys(theme).forEach((function(prop){if(stringPrototypeBlacklist.indexOf(prop)!==-1){console.log("warn: ".red+("String.prototype"+prop).magenta+" is probably something you don't want to override. "+"Ignoring style name")}else{if(typeof theme[prop]==="string"){colors[prop]=colors[theme[prop]]}else{var tmp=colors[theme[prop][0]];for(var t=1;t=2,has16m:level>=3}}function supportsColor(stream){if(forceColor===false){return 0}if(hasFlag("color=16m")||hasFlag("color=full")||hasFlag("color=truecolor")){return 3}if(hasFlag("color=256")){return 2}if(stream&&!stream.isTTY&&forceColor!==true){return 0}var min=forceColor?1:0;if(process.platform==="win32"){var osRelease=os.release().split(".");if(Number(process.versions.node.split(".")[0])>=8&&Number(osRelease[0])>=10&&Number(osRelease[2])>=10586){return Number(osRelease[2])>=14931?3:2}return 1}if("CI"in env){if(["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some((function(sign){return sign in env}))||env.CI_NAME==="codeship"){return 1}return min}if("TEAMCITY_VERSION"in env){return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION)?1:0}if("TERM_PROGRAM"in env){var version=parseInt((env.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(env.TERM_PROGRAM){case"iTerm.app":return version>=3?3:2;case"Hyper":return 3;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(env.TERM)){return 2}if(/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)){return 1}if("COLORTERM"in env){return 1}if(env.TERM==="dumb"){return min}return min}function getSupportLevel(stream){var level=supportsColor(stream);return translateLevel(level)}module.exports={supportsColor:getSupportLevel,stdout:getSupportLevel(process.stdout),stderr:getSupportLevel(process.stderr)}}).call(this,require("_process"))},{"./has-flag.js":28,_process:43,os:42}],30:[function(require,module,exports){const{AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings}=require("acebase-core");const{StorageSettings:StorageSettings}=require("./storage");const{LocalApi:LocalApi}=require("./api-local");class AceBaseLocalSettings{constructor(options){if(!options){options={}}this.logLevel=options.logLevel||"log";this.storage=options.storage}}class AceBase extends AceBaseBase{constructor(dbname,options){options=new AceBaseLocalSettings(options);super(dbname,options);const apiSettings={db:this,storage:options.storage,logLevel:options.logLevel};this.api=new LocalApi(dbname,apiSettings,ready=>{this.emit("ready")})}}module.exports={AceBase:AceBase,AceBaseLocalSettings:AceBaseLocalSettings}},{"./api-local":31,"./storage":38,"acebase-core":11}],31:[function(require,module,exports){const{Api:Api,Utils:Utils}=require("acebase-core");const{AceBase:AceBase}=require("./acebase-local");const{StorageSettings:StorageSettings}=require("./storage");const{AceBaseStorage:AceBaseStorage,AceBaseStorageSettings:AceBaseStorageSettings}=require("./storage-acebase");const{SQLiteStorage:SQLiteStorage,SQLiteStorageSettings:SQLiteStorageSettings}=require("./storage-sqlite");const{MSSQLStorage:MSSQLStorage,MSSQLStorageSettings:MSSQLStorageSettings}=require("./storage-mssql");const{LocalStorage:LocalStorage,LocalStorageSettings:LocalStorageSettings}=require("./storage-localstorage");const{Node:Node}=require("./node");const{DataIndex:DataIndex}=require("./data-index");class LocalApi extends Api{constructor(dbname="default",settings,readyCallback){super();this.db=settings.db;if(typeof settings.storage==="object"){settings.storage.logLevel=settings.logLevel;if(SQLiteStorageSettings&&(settings.storage instanceof SQLiteStorageSettings||settings.storage.type==="sqlite")){this.storage=new SQLiteStorage(dbname,settings.storage)}else if(MSSQLStorageSettings&&(settings.storage instanceof MSSQLStorageSettings||settings.storage.type==="mssql")){this.storage=new MSSQLStorage(dbname,settings.storage)}else if(LocalStorageSettings&&(settings.storage instanceof LocalStorageSettings||settings.storage.type==="localstorage")){this.storage=new LocalStorage(dbname,settings.storage)}else{const storageSettings=settings.storage instanceof AceBaseStorageSettings?settings.storage:new AceBaseStorageSettings(settings.storage);this.storage=new AceBaseStorage(dbname,storageSettings)}}else{settings.storage=new AceBaseStorageSettings({logLevel:settings.logLevel});this.storage=new AceBaseStorage(dbname,settings.storage)}this.storage.on("ready",readyCallback)}stats(options){return Promise.resolve(this.storage.stats)}subscribe(path,event,callback){this.storage.subscriptions.add(path,event,callback)}unsubscribe(path,event=undefined,callback=undefined){this.storage.subscriptions.remove(path,event,callback)}set(path,value,flags=undefined){return Node.update(this.storage,path,value,{merge:false})}update(path,updates,flags=undefined){return Node.update(this.storage,path,updates,{merge:true})}get(path,options){return Node.getValue(this.storage,path,options)}transaction(path,callback){return Node.transaction(this.storage,path,callback)}exists(path){return Node.exists(this.storage,path)}query2(path,query,options={snapshots:false,include:undefined,exclude:undefined,child_objects:undefined}){}query(path,query,options={snapshots:false,include:undefined,exclude:undefined,child_objects:undefined,eventHandler:event=>{}}){if(typeof options!=="object"){options={}}if(typeof options.snapshots==="undefined"){options.snapshots=false}const sortMatches=matches=>{matches.sort((a,b)=>{const compare=i=>{const o=query.order[i];let left=a.val[o.key];let right=b.val[o.key];if(typeof left==="undefined"&&typeof right!=="undefined"){return o.ascending?-1:1}if(typeof left!=="undefined"&&typeof right==="undefined"){return o.ascending?1:-1}if(typeof left==="undefined"&&typeof right==="undefined"){return 0}if(left==right){if(iright){return o.ascending?1:-1}};return compare(0)})};const loadResultsData=(preResults,options)=>{if(preResults.length===0){return Promise.resolve([])}const maxBatchSize=50;let batches=[];const items=preResults.map((result,index)=>({path:result.path,index:index}));while(items.length>0){let batchItems=items.splice(0,maxBatchSize);batches.push(batchItems)}const results=[];const nextBatch=()=>{const batch=batches.shift();return Promise.all(batch.map(item=>{const{path:path,index:index}=item;return Node.getValue(this.storage,path,options).then(val=>{if(val===null){this.storage.debug.warn(`Indexed result "/${path}" does not have a record!`);return}const result={path:path,val:val};if(stepsExecuted.sorted){results[index]=result}else{results.push(result);if(!stepsExecuted.skipped&&results.length>query.skip+query.take){sortMatches(results);results.pop()}}})})).then(()=>{if(batches.length>0){return nextBatch()}})};return nextBatch().then(()=>{return results})};const isWildcardPath=path.indexOf("*")>=0||path.indexOf("$")>=0;const availableIndexes=this.storage.indexes.get(path);const usingIndexes=[];query.filters.forEach(filter=>{if(filter.index){return}const indexesOnKey=availableIndexes.filter(index=>index.key===filter.key).filter(index=>{return index.validOperators.includes(filter.op)});if(indexesOnKey.length>=1){const otherFilterKeys=query.filters.filter(f=>f!==filter).map(f=>f.key);const sortKeys=query.order.map(o=>o.key).filter(key=>key!==filter.key);const beneficialIndexes=indexesOnKey.map(index=>{const availableKeys=index.includeKeys.concat(index.key);const forOtherFilters=availableKeys.filter(key=>otherFilterKeys.indexOf(key)>=0);const forSorting=availableKeys.filter(key=>sortKeys.indexOf(key)>=0);const forBoth=forOtherFilters.concat(forSorting.filter(index=>forOtherFilters.indexOf(index)<0));const points={filters:forOtherFilters.length,sorting:forSorting.length*(query.take>0?forSorting.length:1),both:forBoth.length*forBoth.length,get total(){return this.filters+this.sorting+this.both}};return{index:index,points:points.total,filterKeys:forOtherFilters,sortKeys:forSorting}});beneficialIndexes.sort((a,b)=>a.points>b.points?-1:1);const bestBenificialIndex=beneficialIndexes[0];filter.index=bestBenificialIndex.index;bestBenificialIndex.filterKeys.forEach(key=>{query.filters.filter(f=>f!==filter&&f.key===key).forEach(f=>{if(!DataIndex.validOperators.includes(f.op)){return}f.indexUsage="filter";f.index=bestBenificialIndex.index})});bestBenificialIndex.sortKeys.forEach(key=>{query.order.filter(s=>s.key===key).forEach(s=>{s.index=bestBenificialIndex.index})})}if(filter.index){usingIndexes.push({index:filter.index,description:filter.index.description})}});if(query.order.length>0&&query.take>0){query.order.forEach(sort=>{if(sort.index){return}sort.index=availableIndexes.filter(index=>index.key===sort.key).find(index=>index.type==="normal")})}const indexDescriptions=usingIndexes.map(index=>index.description).join(", ");usingIndexes.length>0&&this.storage.debug.log(`Using indexes for query: ${indexDescriptions}`);const tableScanFilters=query.filters.filter(filter=>!filter.index);const specialOpsRegex=/^[a-z]+\:/i;if(tableScanFilters.some(filter=>specialOpsRegex.test(filter.op))){const f=tableScanFilters.find(filter=>specialOpsRegex.test(filter.op));const err=new Error(`query contains operator "${f.op}" which requires a special index that was not found on path "${path}", key "${f.key}"`);return Promise.reject(err)}const allowedTableScanOperators=["<","<=","==","!=",">=",">","like","!like","in","!in","matches","!matches","between","!between","has","!has","contains","!contains"];for(let i=0;i0){const keys=tableScanFilters.reduce((keys,f)=>{if(keys.indexOf(f.key)<0){keys.push(f.key)}return keys},[]).map(key=>`"${key}"`);const err=new Error(`This wildcard path query on "/${path}" requires index(es) on key(s): ${keys.join(", ")}. Create the index(es) and retry`);return Promise.reject(err)}const indexScanPromises=[];query.filters.forEach(filter=>{if(filter.index&&filter.indexUsage!=="filter"){let promise=filter.index.query(filter.op,filter.compare).then(results=>{options.eventHandler&&options.eventHandler({name:"stats",type:"index_query",source:filter.index.description,stats:results.stats});if(results.hints.length>0){options.eventHandler&&options.eventHandler({name:"hints",type:"index_query",source:filter.index.description,hints:results.hints})}return results});const resultFilters=query.filters.filter(f=>f.index===filter.index&&f.indexUsage==="filter");if(resultFilters.length>0){promise=promise.then(results=>{resultFilters.forEach(filter=>{results=results.filterMetadata(filter.key,filter.op,filter.compare)});return results})}indexScanPromises.push(promise)}});const stepsExecuted={filtered:query.filters.length===0,skipped:query.skip===0,taken:query.take===0,sorted:query.order.length===0,preDataLoaded:false,dataLoaded:false};if(query.filters.length===0&&query.take===0){this.storage.debug.error(`Filterless queries must use .take to limit the results. Defaulting to 100 for query on path "${path}"`);query.take=100}if(query.filters.length===0&&query.order.length>0&&query.order[0].index){const sortIndex=query.order[0].index;this.storage.debug.log(`Using index for sorting: ${sortIndex.description}`);const promise=sortIndex.take(query.skip,query.take,query.order[0].ascending).then(results=>{options.eventHandler&&options.eventHandler({name:"stats",type:"sort_index_take",source:filter.index.description,stats:results.stats});if(results.hints.length>0){options.eventHandler&&options.eventHandler({name:"hints",type:"sort_index_take",source:filter.index.description,hints:results.hints})}return results});indexScanPromises.push(promise);stepsExecuted.skipped=true;stepsExecuted.taken=true;stepsExecuted.sorted=true}return Promise.all(indexScanPromises).then(indexResultSets=>{let indexedResults=[];if(indexResultSets.length===1){const resultSet=indexResultSets[0];indexedResults=resultSet.map(match=>{const result={key:match.key,path:match.path,val:{[resultSet.filterKey]:match.value}};match.metadata&&Object.assign(result.val,match.metadata);return result});stepsExecuted.filtered=true}else if(indexResultSets.length>1){indexResultSets.sort((a,b)=>a.length{const result={key:match.key,path:match.path,val:{[shortestSet.filterKey]:match.value}};const matchedInAllSets=otherSets.every(set=>set.findIndex(m=>match.path===match.path)>=0);if(matchedInAllSets){match.metadata&&Object.assign(result.val,match.metadata);otherSets.forEach(set=>{const otherResult=set.find(r=>r.path===result.path);result.val[set.filterKey]=otherResult.value;otherResult.metadata&&Object.assign(result.val,otherResult.metadata)});results.push(result)}return results},[]);stepsExecuted.filtered=true}if(isWildcardPath||indexScanPromises.length>0&&tableScanFilters.length===0){if(query.order.length===0||query.order.every(o=>o.index)){stepsExecuted.preDataLoaded=true;if(!stepsExecuted.sorted&&query.order.length>0){sortMatches(indexedResults)}stepsExecuted.sorted=true;if(!stepsExecuted.skipped&&query.skip>0){indexedResults=indexedResults.slice(query.skip)}if(!stepsExecuted.taken&&query.take>0){indexedResults=indexedResults.slice(0,query.take)}stepsExecuted.skipped=true;stepsExecuted.taken=true;if(!options.snapshots){return indexedResults}const childOptions={include:options.include,exclude:options.exclude,child_objects:options.child_objects};return loadResultsData(indexedResults,childOptions).then(results=>{stepsExecuted.dataLoaded=true;return results})}if(options.snapshots||!stepsExecuted.sorted){const loadPartialResults=query.order.length>0;const childOptions=loadPartialResults?{include:query.order.map(order=>order.key)}:{include:options.include,exclude:options.exclude,child_objects:options.child_objects};return loadResultsData(indexedResults,childOptions).then(results=>{if(query.order.length>0){sortMatches(results)}stepsExecuted.sorted=true;if(query.skip>0){results=results.slice(query.skip)}if(query.take>0){results=results.slice(0,query.take)}stepsExecuted.skipped=true;stepsExecuted.taken=true;if(options.snapshots&&loadPartialResults){return loadResultsData(results,{include:options.include,exclude:options.exclude,child_objects:options.child_objects})}return results})}else{return indexedResults}}let indexKeyFilter;if(indexedResults.length>0){indexKeyFilter=indexedResults.map(result=>result.key)}const promises=[];let matches=[];let preliminaryStop=false;const loadPartialData=query.order.length>0;const childOptions=loadPartialData?{include:query.order.map(order=>order.key)}:{include:options.include,exclude:options.exclude,child_objects:options.child_objects};return Node.getChildren(this.storage,path,indexKeyFilter).next(child=>{if(child.type===Node.VALUE_TYPES.OBJECT){if(!child.address){return}if(preliminaryStop){return false}const p=Node.matches(this.storage,child.address.path,tableScanFilters).then(isMatch=>{if(!isMatch){return null}const childPath=child.address.path;if(options.snapshots||query.order.length>0){return Node.getValue(this.storage,childPath,childOptions).then(val=>{return{path:childPath,val:val}})}else{return{path:childPath}}}).then(result=>{if(result!==null){matches.push(result);if(query.take>0&&matches.length>query.take+query.skip){if(query.order.length>0){sortMatches(matches)}else{preliminaryStop=true}matches.pop()}}});promises.push(p)}}).catch(reason=>{this.storage.debug.warn(`Error getting child stream: ${reason}`);return[]}).then(()=>{return Promise.all(promises).then(()=>{stepsExecuted.preDataLoaded=loadPartialData;stepsExecuted.dataLoaded=!loadPartialData;if(query.order.length>0){sortMatches(matches)}stepsExecuted.sorted=true;if(query.skip>0){matches=matches.slice(query.skip)}stepsExecuted.skipped=true;if(query.take>0){matches=matches.slice(0,query.take)}stepsExecuted.taken=true;if(!stepsExecuted.dataLoaded){return loadResultsData(matches,{include:options.include,exclude:options.exclude,child_objects:options.child_objects}).then(results=>{stepsExecuted.dataLoaded=true;return results})}return matches})})}).then(matches=>{if(!stepsExecuted.sorted&&query.order.length>0){sortMatches(matches)}if(!options.snapshots){matches=matches.map(match=>match.path)}if(!stepsExecuted.skipped&&query.skip>0){matches=matches.slice(query.skip)}if(!stepsExecuted.taken&&query.take>0){matches=matches.slice(0,query.take)}if(options.monitor===true){options.monitor={add:true,change:true,remove:true}}if(typeof options.monitor==="object"&&(options.monitor.add||options.monitor.change||options.monitor.remove)){const matchedPaths=options.snapshots?matches.map(match=>match.path):matches.slice();const ref=this.db.ref(path);const removeMatch=path=>{const index=matchedPaths.indexOf(path);if(index<0){return}matchedPaths.splice(index,1)};const addMatch=path=>{if(matchedPaths.includes(path)){return}matchedPaths.push(path)};const stopMonitoring=()=>{this.unsubscribe(ref.path,"notify_child_changed",childChangedCallback);this.unsubscribe(ref.path,"notify_child_added",childAddedCallback);this.unsubscribe(ref.path,"notify_child_removed",childRemovedCallback)};const childChangedCallback=(err,path,newValue,oldValue)=>{const wasMatch=matchedPaths.includes(path);let keepMonitoring=true;const checkKeys=[];query.filters.forEach(f=>!checkKeys.includes(f.key)&&checkKeys.push(f.key));const seenKeys=[];typeof oldValue==="object"&&Object.keys(oldValue).forEach(key=>!seenKeys.includes(key)&&seenKeys.push(key));typeof newValue==="object"&&Object.keys(newValue).forEach(key=>!seenKeys.includes(key)&&seenKeys.push(key));const missingKeys=[];let isMatch=seenKeys.every(key=>{if(!checkKeys.includes(key)){return true}const filters=query.filters.filter(filter=>filter.key===key);return filters.every(filter=>{if(allowedTableScanOperators.includes(filter.op)){return this.storage.test(newValue[key],filter.op,filter.compare)}if(filter.index.constructor.name==="FullTextDataIndex"&&filter.index.localeKey&&!seenKeys.includes(filter.index.localeKey)){missingKeys.push(filter.index.localeKey);return true}return filter.index.test(newValue,filter.op,filter.compare)})});if(isMatch){missingKeys.push(...checkKeys.filter(key=>!seenKeys.includes(key)));let promise=Promise.resolve(true);if(!wasMatch&&missingKeys.length>0){const filterQueue=query.filters.filter(f=>missingKeys.includes(f.key));const simpleFilters=filterQueue.filter(f=>allowedTableScanOperators.includes(f.op));const indexFilters=filterQueue.filter(f=>!allowedTableScanOperators.includes(f.op));const processFilters=()=>{const checkIndexFilters=()=>{const keysToLoad=indexFilters.reduce((keys,filter)=>{if(!keys.includes(filter.key)){keys.push(filter.key)}if(filter.index.constructor.name==="FullTextDataIndex"&&filter.index.localeKey&&!keys.includes(filter.index.localeKey)){keys.push(filter.index.localeKey)}return keys},[]);return Node.getValue(this.storage,path,{include:keysToLoad}).then(val=>{if(val===null){return false}return indexFilters.every(filter=>filter.index.test(val,filter.op,filter.compare))})};if(simpleFilters.length>0){return Node.matches(this.storage,path,simpleFilters).then(isMatch=>{if(isMatch){if(indexFilters.length===0){return true}return checkIndexFilters()}return false})}else{return checkIndexFilters()}};promise=processFilters()}return promise.then(isMatch=>{if(isMatch){if(!wasMatch){addMatch(path)}let gotValue=value=>{if(wasMatch&&options.monitor.change){keepMonitoring=options.eventHandler({name:"change",path:path,value:value})}else if(!wasMatch&&options.monitor.add){keepMonitoring=options.eventHandler({name:"add",path:path,value:value})}if(keepMonitoring===false){stopMonitoring()}};if(options.snapshots){const loadOptions={include:options.include,exclude:options.exclude,child_objects:options.child_objects};return this.storage.getNodeValue(path,loadOptions).then(gotValue)}else{return gotValue(newValue)}}else if(wasMatch){removeMatch(path);if(options.monitor.remove){keepMonitoring=options.eventHandler({name:"remove",path:path,value:oldValue})}}if(keepMonitoring===false){stopMonitoring()}})}else{if(wasMatch){removeMatch(path);if(options.monitor.remove){keepMonitoring=options.eventHandler({name:"remove",path:path,value:oldValue});if(keepMonitoring===false){stopMonitoring()}}}}};const childAddedCallback=(err,path,newValue,oldValue)=>{let isMatch=query.filters.every(filter=>{if(allowedTableScanOperators.includes(filter.op)){return this.storage.test(newValue[filter.key],filter.op,filter.compare)}else{return filter.index.test(newValue,filter.op,filter.compare)}});let keepMonitoring=true;if(isMatch){addMatch(path);if(options.monitor.add){keepMonitoring=options.eventHandler({name:"add",path:path,value:options.snapshots?newValue:null})}}if(keepMonitoring===false){stopMonitoring()}};const childRemovedCallback=(err,path,newValue,oldValue)=>{let keepMonitoring=true;removeMatch(path);if(options.monitor.remove){keepMonitoring=options.eventHandler({name:"remove",path:path,value:options.snapshots?oldValue:null})}if(keepMonitoring===false){stopMonitoring()}};if(options.monitor.add||options.monitor.change||options.monitor.remove){this.subscribe(ref.path,"notify_child_changed",childChangedCallback)}if(options.monitor.remove){this.subscribe(ref.path,"notify_child_removed",childRemovedCallback)}if(options.monitor.add){this.subscribe(ref.path,"notify_child_added",childAddedCallback)}}return matches})}createIndex(path,key,options){return this.storage.indexes.create(path,key,options)}getIndexes(){return Promise.resolve(this.storage.indexes.list())}reflect(path,type,args){const getChildren=(path,limit=50,skip=0)=>{if(typeof limit==="string"){limit=parseInt(limit)}if(typeof skip==="string"){skip=parseInt(skip)}const children=[];let n=0,stop=skip+limit;return Node.getChildren(this.storage,path).next(childInfo=>{n++;if(limit===0||n<=stop&&n>skip){children.push({key:typeof childInfo.key==="string"?childInfo.key:childInfo.index,type:childInfo.valueTypeName,value:childInfo.value,address:typeof childInfo.address==="object"&&"pageNr"in childInfo.address?{pageNr:childInfo.address.pageNr,recordNr:childInfo.address.recordNr}:undefined})}if(limit>0&&n>stop){return false}}).then(()=>{return{more:limit!==0&&n>stop,list:children}})};switch(type){case"children":{return getChildren(path,args.limit,args.skip)}case"info":{const info={key:"",exists:false,type:"unknown",value:undefined,children:{more:false,list:[]}};return Node.getInfo(this.storage,path).then(nodeInfo=>{info.key=nodeInfo.key;info.exists=nodeInfo.exists;info.type=nodeInfo.valueTypeName;info.value=nodeInfo.value;let hasChildren=nodeInfo.exists&&nodeInfo.address&&[Node.VALUE_TYPES.OBJECT,Node.VALUE_TYPES.ARRAY].includes(nodeInfo.type);if(hasChildren){return getChildren(path,args.child_limit,args.child_skip)}}).then(children=>{info.children=children;return info})}}}export(path,stream,options={format:"json"}){return this.storage.exportNode(path,stream,options)}}module.exports={LocalApi:LocalApi}},{"./acebase-local":30,"./data-index":39,"./node":36,"./storage":38,"./storage-acebase":39,"./storage-localstorage":37,"./storage-mssql":39,"./storage-sqlite":39,"acebase-core":11}],32:[function(require,module,exports){const{DataReference:DataReference,DataSnapshot:DataSnapshot,EventSubscription:EventSubscription,PathReference:PathReference,TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions}=require("acebase-core");const{AceBase:AceBase,AceBaseLocalSettings:AceBaseLocalSettings}=require("./acebase-local");const{LocalStorageSettings:LocalStorageSettings}=require("./storage-localstorage");const acebase={AceBase:AceBase,AceBaseLocalSettings:AceBaseLocalSettings,DataReference:DataReference,DataSnapshot:DataSnapshot,EventSubscription:EventSubscription,PathReference:PathReference,TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions,LocalStorageSettings:LocalStorageSettings};class BrowserAceBase extends acebase.AceBase{constructor(name,settings){settings=settings||{};settings.storage=new acebase.LocalStorageSettings;if(settings.temp===true){settings.storage.session=true;delete settings.temp}super(name,settings)}}window.AceBase=BrowserAceBase;window.acebase=acebase},{"./acebase-local":30,"./storage-localstorage":37,"acebase-core":11}],33:[function(require,module,exports){const{VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}=require("./node-value-types");const{PathInfo:PathInfo}=require("acebase-core");class NodeInfo{constructor(info){this.path=info.path;this.type=info.type;this.index=info.index;this.key=info.key;this.exists=info.exists;this.address=info.address;this.value=info.value;if(typeof this.path==="string"&&(typeof this.key==="undefined"&&typeof this.index==="undefined")){let pathInfo=PathInfo.get(this.path);if(typeof pathInfo.key==="number"){this.index=pathInfo.key}else{this.key=pathInfo.key}}if(typeof this.exists==="undefined"){this.exists=true}}get valueType(){return this.type}get valueTypeName(){return getValueTypeName(this.valueType)}toString(){if(!this.exists){return`"${this.path}" doesn't exist`}if(this.address){return`"${this.path}" is ${this.valueTypeName} stored at ${this.address.pageNr},${this.address.recordNr}`}else{return`"${this.path}" is ${this.valueTypeName} with value ${this.value}`}}}module.exports={NodeInfo:NodeInfo}},{"./node-value-types":35,"acebase-core":11}],34:[function(require,module,exports){const{PathInfo:PathInfo}=require("acebase-core");const SECOND=1e3;const MINUTE=6e4;const DEBUG_MODE=false;const LOCK_TIMEOUT=DEBUG_MODE?15*MINUTE:90*SECOND;const LOCK_STATE={PENDING:"pending",LOCKED:"locked",EXPIRED:"expired",DONE:"done"};class NodeLocker{constructor(){this._locks=[]}_allowLock(path,tid,forWriting){const pathInfo=PathInfo.get(path);const existing=this._locks.find(otherLock=>otherLock.tid===tid&&otherLock.state===LOCK_STATE.LOCKED&&(otherLock.path===path||pathInfo.isDescendantOf(otherLock.path))&&(otherLock.forWriting||!forWriting));if(typeof existing==="object"){return{allow:true}}const conflict=this._locks.filter(otherLock=>otherLock.tid!==tid&&otherLock.state===LOCK_STATE.LOCKED).find(otherLock=>{return(forWriting||otherLock.forWriting)&&(path===otherLock.path||pathInfo.isDescendantOf(otherLock.path))});const clashes=typeof conflict!=="undefined";return{allow:!clashes,conflict:conflict}}_processLockQueue(){const pending=this._locks.filter(lock=>lock.state===LOCK_STATE.PENDING&&(lock.waitingFor===null||lock.waitingFor.state!==LOCK_STATE.LOCKED)).sort((a,b)=>{if(a.priority&&!b.priority){return-1}else if(!a.priority&&b.priority){return 1}return a.requested{const check=this._allowLock(lock.path,lock.tid,lock.forWriting);lock.waitingFor=check.conflict||null;if(check.allow){this.lock(lock).then(lock.resolve).catch(lock.reject)}})}lock(path,tid,forWriting=true,comment="",options={withPriority:false,noTimeout:false}){let lock,proceed;if(path instanceof NodeLock){lock=path;lock.comment=`(retry: ${lock.comment})`;proceed=true}else if(this._locks.findIndex(l=>l.tid===tid&&l.state===LOCK_STATE.EXPIRED)>=0){return Promise.reject(new Error(`lock on tid ${tid} has expired, not allowed to continue`))}else{lock=new NodeLock(this,path,tid,forWriting,options.withPriority===true);lock.comment=comment;this._locks.push(lock);const check=this._allowLock(path,tid,forWriting);lock.waitingFor=check.conflict||null;proceed=check.allow}if(proceed){lock.state=LOCK_STATE.LOCKED;if(typeof lock.granted==="number"){}else{lock.granted=Date.now();if(options.noTimeout!==true){lock.expires=Date.now()+LOCK_TIMEOUT;lock.timeout=setTimeout(()=>{if(lock.state!==LOCK_STATE.LOCKED){return}console.error(`lock :: ${lock.forWriting?"write":"read"} lock on path "/${lock.path}" by tid ${lock.tid} took too long, ${lock.comment}`);lock.state=LOCK_STATE.EXPIRED;this._processLockQueue()},LOCK_TIMEOUT)}}return Promise.resolve(lock)}else{console.assert(lock.state===LOCK_STATE.PENDING);const p=new Promise((resolve,reject)=>{lock.resolve=resolve;lock.reject=reject});return p}}unlock(lockOrId,comment,processQueue=true){let lock,i;if(lockOrId instanceof NodeLock){lock=lockOrId;i=this._locks.indexOf(lock)}else{let id=lockOrId;i=this._locks.findIndex(l=>l.id===id);lock=this._locks[i]}if(i<0){const msg=`lock on "/${lock.path}" for tid ${lock.tid} wasn't found; ${comment}`;return Promise.reject(new Error(msg))}lock.state=LOCK_STATE.DONE;clearTimeout(lock.timeout);this._locks.splice(i,1);processQueue&&this._processLockQueue();return Promise.resolve(lock)}list(){return this._locks||[]}isAllowed(path,tid,forWriting){return this._allowLock(path,tid,forWriting).allow}}let lastid=0;class NodeLock{static get LOCK_STATE(){return LOCK_STATE}constructor(locker,path,tid,forWriting,priority=false){this.locker=locker;this.path=path;this.tid=tid;this.forWriting=forWriting;this.priority=priority;this.state=LOCK_STATE.PENDING;this.requested=Date.now();this.granted=undefined;this.expires=undefined;this.comment="";this.waitingFor=null;this.id=++lastid}release(comment){return this.locker.unlock(this,comment||this.comment)}moveToParent(){const parentPath=PathInfo.get(this.path).parentPath;const allowed=this.locker.isAllowed(parentPath,this.tid,this.forWriting);if(allowed){this.waitingFor=null;this.path=parentPath;this.comment=`moved to parent: ${this.comment}`;return Promise.resolve(this)}else{this.locker.unlock(this,`moveLockToParent: ${this.comment}`,false);return this.locker.lock(parentPath,this.tid,this.forWriting,`moved to parent (queued): ${this.comment}`,{withPriority:true}).then(newLock=>{return newLock})}}moveTo(otherPath,forWriting){const allowed=this.locker.isAllowed(otherPath,this.tid,forWriting);if(allowed){this.waitingFor=null;this.path=otherPath;this.forWriting=forWriting;this.comment=`moved to "/${otherPath}": ${this.comment}`;return Promise.resolve(this)}else{this.locker.unlock(this,`moving to "/${otherPath}": ${this.comment}`,false);return this.locker.lock(otherPath,this.tid,forWriting,`moved to "/${otherPath}" (queued): ${this.comment}`,{withPriority:true}).then(newLock=>{return newLock})}}}module.exports={NodeLocker:NodeLocker,NodeLock:NodeLock}},{"acebase-core":11}],35:[function(require,module,exports){const VALUE_TYPES={OBJECT:1,ARRAY:2,NUMBER:3,BOOLEAN:4,STRING:5,DATETIME:6,BINARY:8,REFERENCE:9};function getValueTypeName(valueType){switch(valueType){case VALUE_TYPES.ARRAY:return"array";case VALUE_TYPES.BINARY:return"binary";case VALUE_TYPES.BOOLEAN:return"boolean";case VALUE_TYPES.DATETIME:return"date";case VALUE_TYPES.NUMBER:return"number";case VALUE_TYPES.OBJECT:return"object";case VALUE_TYPES.REFERENCE:return"reference";case VALUE_TYPES.STRING:return"string";default:"unknown"}}module.exports={VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}},{}],36:[function(require,module,exports){const{Storage:Storage}=require("./storage");const{NodeInfo:NodeInfo}=require("./node-info");const{VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}=require("./node-value-types");const colors=require("colors");class Node{static get VALUE_TYPES(){return VALUE_TYPES}static getInfo(storage,path,options={no_cache:false}){if(options&&!options.no_cache){let cachedInfo=storage.nodeCache.find(path);if(cachedInfo){return Promise.resolve(cachedInfo)}}return storage.getNodeInfo(path).then(info=>{if(options&&!options.no_cache){storage.nodeCache.update(info)}return info})}static update(storage,path,value,options={merge:true}){if(options.merge){return storage.updateNode(path,value)}else{return storage.setNode(path,value)}}static exists(storage,path){return storage.getNodeInfo(path).then(nodeInfo=>{return nodeInfo.exists})}static getValue(storage,path,options={include:undefined,exclude:undefined,child_objects:true}){if(!options){options={}}if(typeof options.include!=="undefined"&&!(options.include instanceof Array)){throw new TypeError(`options.include must be an array of key names`)}if(typeof options.exclude!=="undefined"&&!(options.exclude instanceof Array)){throw new TypeError(`options.exclude must be an array of key names`)}if(["undefined","boolean"].indexOf(typeof options.child_objects)<0){throw new TypeError(`options.child_objects must be a boolean`)}return storage.getNodeValue(path,options)}static getChildInfo(storage,path,childKeyOrIndex){let childInfo;return storage.getChildren(path,{keyFilter:[childKeyOrIndex]}).next(info=>{childInfo=info}).then(()=>{return childInfo})}static getChildren(storage,path,keyFilter=undefined){return storage.getChildren(path,{keyFilter:keyFilter})}static remove(storage,path){return storage.removeNode(path)}static set(storage,path,value){return Node.update(storage,path,value,{merge:false})}static transaction(storage,path,callback){return storage.transactNode(path,callback)}static matches(storage,path,criteria,options){return storage.matchNode(path,criteria,options)}}class NodeChange{static get CHANGE_TYPE(){return{UPDATE:"update",DELETE:"delete",INSERT:"insert"}}constructor(keyOrIndex,changeType,oldValue,newValue){this.keyOrIndex=keyOrIndex;this.changeType=changeType;this.oldValue=oldValue;this.newValue=newValue}}class NodeChangeTracker{constructor(path){this.path=path;this._changes=[];this._oldValue=undefined;this._newValue=undefined}addDelete(keyOrIndex,oldValue){this._changes.push(new NodeChange(keyOrIndex,NodeChange.CHANGE_TYPE.DELETE,oldValue,null))}addUpdate(keyOrIndex,oldValue,newValue){this._changes.push(new NodeChange(keyOrIndex,NodeChange.CHANGE_TYPE.UPDATE,oldValue,newValue))}addInsert(keyOrIndex,newValue){this._changes.push(new NodeChange(keyOrIndex,NodeChange.CHANGE_TYPE.INSERT,null,newValue))}add(keyOrIndex,currentValue,newValue){if(currentValue===null){if(newValue===null){throw new Error(`Wrong logic for node change on "${this.nodeInfo.path}/${keyOrIndex}" - both old and new values are null`)}this.addInsert(keyOrIndex,newValue)}else if(newValue===null){this.addDelete(keyOrIndex,currentValue)}else{this.addUpdate(keyOrIndex,currentValue,newValue)}}get updates(){return this._changes.filter(change=>change.changeType===NodeChange.CHANGE_TYPE.UPDATE)}get deletes(){return this._changes.filter(change=>change.changeType===NodeChange.CHANGE_TYPE.DELETE)}get inserts(){return this._changes.filter(change=>change.changeType===NodeChange.CHANGE_TYPE.INSERT)}get all(){return this._changes}get totalChanges(){return this._changes.length}get(keyOrIndex){return this._changes.find(change=>change.keyOrIndex===keyOrIndex)}hasChanged(keyOrIndex){return!!this.get(keyOrIndex)}get newValue(){if(typeof this._newValue==="object"){return this._newValue}if(typeof this._oldValue==="undefined"){throw new TypeError(`oldValue is not set`)}let newValue={};Object.keys(this.oldValue).forEach(key=>newValue[key]=oldValue[key]);this.deletes.forEach(change=>delete newValue[change.key]);this.updates.forEach(change=>newValue[change.key]=change.newValue);this.inserts.forEach(change=>newValue[change.key]=change.newValue);return newValue}set newValue(value){this._newValue=value}get oldValue(){if(typeof this._oldValue==="object"){return this._oldValue}if(typeof this._newValue==="undefined"){throw new TypeError(`newValue is not set`)}let oldValue={};Object.keys(this.newValue).forEach(key=>oldValue[key]=newValue[key]);this.deletes.forEach(change=>oldValue[change.key]=change.oldValue);this.updates.forEach(change=>oldValue[change.key]=change.oldValue);this.inserts.forEach(change=>delete oldValue[change.key]);return oldValue}set oldValue(value){this._oldValue=value}get typeChanged(){return typeof this.oldValue!==typeof this.newValue||this.oldValue instanceof Array&&!(this.newValue instanceof Array)||this.newValue instanceof Array&&!(this.oldValue instanceof Array)}static create(path,oldValue,newValue){const changes=new NodeChangeTracker(path);changes.oldValue=oldValue;changes.newValue=newValue;typeof oldValue==="object"&&Object.keys(oldValue).forEach(key=>{if(typeof newValue==="object"&&key in newValue&&newValue!==null){changes.add(key,oldValue[key],newValue[key])}else{changes.add(key,oldValue[key],null)}});typeof newValue==="object"&&Object.keys(newValue).forEach(key=>{if(typeof oldValue!=="object"||!(key in oldValue)||oldValue[key]===null){changes.add(key,null,newValue[key])}});return changes}}module.exports={Node:Node,NodeInfo:NodeInfo}},{"./node-info":33,"./node-value-types":35,"./storage":38,colors:22}],37:[function(require,module,exports){const{debug:debug,ID:ID,PathReference:PathReference,PathInfo:PathInfo,ascii85:ascii85}=require("acebase-core");const{NodeInfo:NodeInfo}=require("./node-info");const{VALUE_TYPES:VALUE_TYPES}=require("./node-value-types");const{Storage:Storage,StorageSettings:StorageSettings}=require("./storage");class LocalStorageSettings extends StorageSettings{constructor(settings){super(settings);settings=settings||{};this.session=settings.session===true;this.provider=typeof settings.provider==="object"?settings.provider:null}}class LocalStorageNodeAddress{constructor(containerPath){this.path=containerPath}}class LocalStorageNodeInfo extends NodeInfo{constructor(info){super(info);this.address;this.revision=info.revision;this.revision_nr=info.revision_nr;this.created=info.created;this.modified=info.modified}}class LocalStorage extends Storage{constructor(dbname,settings){super(dbname,settings);this._init()}_init(){if(this.settings.provider!==null&&typeof this.settings.provider==="object"){this._localStorage=this.settings.provider}else{if(!this.settings.session&&typeof localStorage==="undefined"){throw new Error(`No localStorage available. If you are on Node: npm i node-localstorage`)}if(this.settings.session===true&&typeof sessionStorage==="undefined"){throw new Error(`No sessionStorage available`)}this._localStorage=this.settings.session===true?sessionStorage:localStorage}this.debug.log(`Database "${this.name}" details:`.intro);this.debug.log(`- Type: LocalStorage`);this.debug.log(`- Max inline value size: ${this.settings.maxInlineValueSize}`.intro);return this.getNodeInfo("").then(info=>{if(!info.exists){return this._writeNode("",{})}}).then(()=>{return this.indexes.load()}).then(()=>{this.emit("ready")})}get _keyPrefix(){return`${this.name}.acebase::`}_getPathFromKey(key){return key.slice(this._keyPrefix.length)}_getKeyFromPath(path){return`${this._keyPrefix}${path}`}_storeNode(path,info){const getTypedChildValue=val=>{if(val===null){throw new Error(`Not allowed to store null values. remove the property`)}else if(["string","number","boolean"].includes(typeof val)){return val}else if(val instanceof Date){return{type:VALUE_TYPES.DATETIME,value:val.getTime()}}else if(val instanceof PathReference){return{type:VALUE_TYPES.REFERENCE,value:child.path}}else if(val instanceof ArrayBuffer){return{type:VALUE_TYPES.BINARY,value:ascii85.encode(val)}}else if(typeof val==="object"){console.assert(Object.keys(val).length===0,"child object stored in parent can only be empty");return val}};const unprocessed=`Caller should have pre-processed the value by converting it to a string`;if(info.type===VALUE_TYPES.ARRAY&&info.value instanceof Array){console.warn(`Unprocessed array. ${unprocessed}`);const obj={};for(let i=0;i{info.value[key]=getTypedChildValue(original[key])})}const json=JSON.stringify(info);this._localStorage.setItem(this._getKeyFromPath(path),json)}_readNode(path){let val=this._localStorage.getItem(this._getKeyFromPath(path));if(val===null){return null}val=JSON.parse(val);const getTypedChildValue=val=>{if(val.type===VALUE_TYPES.BINARY){return ascii85.decode(val.value)}else if(val.type===VALUE_TYPES.DATETIME){return new Date(val.value)}else if(val.type===VALUE_TYPES.REFERENCE){return new PathReference(val.value)}else{throw new Error(`Unhandled child value type ${val.type}`)}};const node={type:val.type,value:val.value,revision:val.revision,revision_nr:val.revision_nr,created:val.created,modified:val.modified};switch(val.type){case VALUE_TYPES.ARRAY:case VALUE_TYPES.OBJECT:{const obj=val.value;Object.keys(obj).forEach(key=>{let item=obj[key];if(typeof item==="object"&&"type"in item){obj[key]=getTypedChildValue(item)}});node.value=obj;break}case VALUE_TYPES.BINARY:{node.value=ascii85.decode(val.value);break}case VALUE_TYPES.STRING:{node.value=val.value;break}case VALUE_TYPES.REFERENCE:{node.value=new PathReference(val.value);break}default:throw new Error(`Invalid standalone record value type`)}return node}_getTypeFromStoredValue(val){let type;if(typeof val==="string"){type=VALUE_TYPES.STRING}else if(typeof val==="number"){type=VALUE_TYPES.NUMBER}else if(typeof val==="boolean"){type=VALUE_TYPES.BOOLEAN}else if(val instanceof Array){type=VALUE_TYPES.ARRAY}else if(typeof val==="object"){if("type"in val){type=val.type;val=val.value;if(type===VALUE_TYPES.DATETIME){val=new Date(val)}else if(type===VALUE_TYPES.REFERENCE){val=new PathReference(val)}}else{type=VALUE_TYPES.OBJECT}}else{throw new Error(`Unknown value type`)}return{type:type,value:val}}_writeNode(path,value,options={merge:false,revision:null}){if(this.valueFitsInline(value)&&path!==""){throw new Error(`invalid value to store in its own node`)}else if(path===""&&(typeof value!=="object"||value instanceof Array)){throw new Error(`Invalid root node value. Must be an object`)}const currentRow=this._readNode(path);const newRevision=options&&options.revision||ID.generate();let mainNode={type:VALUE_TYPES.OBJECT,value:{}};const childNodeValues={};if(value instanceof Array){mainNode.type=VALUE_TYPES.ARRAY;const obj={};for(let i=0;i{const val=value[key];delete mainNode.value[key];if(val===null){return}if(this.valueFitsInline(val)){mainNode.value[key]=val}else{childNodeValues[key]=val}})}if(currentRow){this.debug.log(`Node "/${path}" is being ${options.merge?"updated":"overwritten"}`.cyan);if(currentIsObjectOrArray||newIsObjectOrArray){const pathInfo=PathInfo.get(path);const keys=[];for(let i=0;i{if(!children.new.includes(key)){children.new.push(key)}})}const changes={insert:children.new.filter(key=>!children.current.includes(key)),update:children.new.filter(key=>children.current.includes(key)),delete:options&&options.merge?Object.keys(value).filter(key=>value[key]===null):children.current.filter(key=>!children.new.includes(key))};Object.keys(childNodeValues).map(key=>{const childPath=PathInfo.getChildPath(path,key);const childValue=childNodeValues[key];this._writeNode(childPath,childValue,{revision:newRevision,merge:false})});const movingNodes=keys.filter(key=>key in mainNode.value);const deleteDedicatedKeys=changes.delete.concat(movingNodes);deleteDedicatedKeys.forEach(key=>{const childPath=PathInfo.getChildPath(path,key);this._deleteNode(childPath)})}this._storeNode(path,{type:mainNode.type,value:mainNode.value,revision:currentRow.revision,revision_nr:currentRow.revision_nr+1,created:currentRow.created,modified:Date.now()})}else{this.debug.log(`Node "/${path}" is being created`.cyan);Object.keys(childNodeValues).map(key=>{const childPath=PathInfo.getChildPath(path,key);const childValue=childNodeValues[key];this._writeNode(childPath,childValue,{revision:newRevision,merge:false})});this._storeNode(path,{type:mainNode.type,value:mainNode.value,revision:newRevision,revision_nr:1,created:Date.now(),modified:Date.now()})}}_deleteNode(path){this._localStorage.removeItem(this._getKeyFromPath(path));for(let i=0;i{let lock,canceled=false;const tid=options&&options.tid||ID.generate();return this.nodeLocker.lock(path,tid,false,"getChildren").then(l=>{lock=l;let row=this._localStorage.getItem(this._getKeyFromPath(path));if(!row){throw new NodeNotFoundError(`Node "/${path}" does not exist`)}row=JSON.parse(row);if(![VALUE_TYPES.OBJECT,VALUE_TYPES.ARRAY].includes(row.type)){return}const isArray=row.type===VALUE_TYPES.ARRAY;const value=row.value;let keys=Object.keys(value);if(options.keyFilter){keys=keys.filter(key=>options.keyFilter.includes(key))}const pathInfo=PathInfo.get(path);keys.length>0&&keys.every(key=>{let child=this._getTypeFromStoredValue(value[key]);const info=new LocalStorageNodeInfo({path:pathInfo.childPath(key),key:isArray?null:key,index:isArray?key:null,type:child.type,address:null,exists:true,value:child.value,revision:row.revision,revision_nr:row.revision_nr,created:row.created,modified:row.modified});canceled=callback(info)===false;return!canceled});if(canceled){return}const childRows=[];for(let i=0;i{const row=childRows[i];if(!row){return}const key=PathInfo.get(row.path).key;if(options.keyFilter&&!options.keyFilter.includes(key)){return handleNextChild(i+1)}const info=new LocalStorageNodeInfo({path:row.path,type:row.type,key:isArray?null:key,index:isArray?key:null,address:new LocalStorageNodeAddress(row.path),exists:true,value:null,revision:row.revision,revision_nr:row.revision_nr,created:new Date(row.created),modified:new Date(row.modified)});canceled=callback(info)===false;if(!canceled){return handleNextChild(i+1)}};return handleNextChild(0)}).then(()=>{lock.release();return canceled}).catch(err=>{lock.release();throw err})};return generator}getNode(path,options={include:undefined,exclude:undefined,child_objects:true,tid:undefined}){const tid=options&&options.tid||ID.generate();let lock;return this.nodeLocker.lock(path,tid,false,"getNode").then(l=>{lock=l;const filtered=options&&(options.include||options.exclude||options.child_objects===false);const pathInfo=PathInfo.get(path);const targetRow=this._readNode(path);if(!targetRow){if(path===""){return null}return lock.moveToParent().then(parentLock=>{lock=parentLock;let parentNode=this._readNode(pathInfo.parentPath);if([VALUE_TYPES.OBJECT,VALUE_TYPES.ARRAY].includes(parentNode.type)&&pathInfo.key in parentNode){return parentNode[pathInfo.key]}return null})}const includeCheck=options.include?new RegExp("^"+options.include.map(p=>"(?:"+p.replace(/\*/g,"[^/\\[]+")+")").join("|")+"(?:$|[/\\[])"):null;const excludeCheck=options.exclude?new RegExp("^"+options.exclude.map(p=>"(?:"+p.replace(/\*/g,"[^/\\[]+")+")").join("|")+"(?:$|[/\\[])"):null;const childRows=[];for(let i=0;ipathInfo.pathKeys.length+1)){include=false}if(include){childRow.path=otherPath;childRows.push(childRow)}}this.debug.log(`Read node "/${path}" and ${filtered?"(filtered) ":""}children from ${childRows.length+1} records`.magenta);const result={revision:targetRow?targetRow.revision:null,value:targetRow.value};const objectToArray=obj=>{const arr=[];Object.keys(obj).forEach(key=>{let index=parseInt(key);arr[index]=obj[index]});return arr};if(targetRow.type===VALUE_TYPES.ARRAY){result.value=objectToArray(result.value)}if(targetRow.type===VALUE_TYPES.OBJECT||targetRow.type===VALUE_TYPES.ARRAY){const targetPathKeys=PathInfo.getPathKeys(path);let value=targetRow.value;for(let i=0;i{console.assert(!(childKey in parent[key]),"child key is in parent value already?! HOW?!");parent[key][childKey]=nodeValue[childKey]})}else{parent[key]=nodeValue}parent=parent[key]}}}else if(childRows.length>0){throw new Error(`multiple records found for non-object value!`)}lock.release();if(options.child_objects===false){Object.keys(result.value).forEach(key=>{if(typeof result.value[key]==="object"&&result.value[key].constructor===Object){console.assert(Object.keys(result.value[key]).length===0);delete result.value[key]}})}if(options.exclude){const process=(obj,keys)=>{if(typeof obj!=="object"){return}const key=keys[0];if(key==="*"){Object.keys(obj).forEach(k=>{process(obj[k],keys.slice(1))})}else if(keys.length>1){key in obj&&process(obj[key],keys.slice(1))}else{delete obj[key]}};options.exclude.forEach(path=>{const checkKeys=PathInfo.getPathKeys(path);process(result.value,checkKeys)})}return result}).catch(err=>{lock.release();throw err})}getNodeInfo(path,options={tid:undefined}){const pathInfo=PathInfo.get(path);const tid=options&&options.tid||ID.generate();let lock;return this.nodeLocker.lock(path,tid,false,"getNodeInfo").then(l=>{lock=l;const node=this._readNode(path);const info=new LocalStorageNodeInfo({path:path,key:typeof pathInfo.key==="string"?pathInfo.key:null,index:typeof pathInfo.key==="number"?pathInfo.key:null,type:node?node.type:0,exists:node!==null,address:node?new LocalStorageNodeAddress(path):null,created:node?new Date(node.created):null,modified:node?new Date(node.modified):null,revision:node?node.revision:null,revision_nr:node?node.revision_nr:null});if(node||path===""){return info}return lock.moveToParent().then(parentLock=>{lock=parentLock;const parent=this._readNode(pathInfo.parentPath);if(parent&&[VALUE_TYPES.OBJECT,VALUE_TYPES.ARRAY].includes(parent.type)&&pathInfo.key in parent.value){info.exists=true;info.value=parent.value[pathInfo.key];info.address=null;info.type=parent.type;info.created=new Date(parent.created);info.modified=new Date(parent.modified);info.revision=parent.revision;info.revision_nr=parent.revision_nr}else{info.address=null}return info})}).then(info=>{lock.release();return info}).catch(err=>{lock&&lock.release();throw err})}removeNode(path,options={tid:undefined}){if(path===""){return Promise.reject(new Error(`Cannot remove the root node`))}const pathInfo=PathInfo.get(path);const tid=options&&options.tid||ID.generate();return this.nodeLocker.lock(pathInfo.parentPath,tid,true,"removeNode").then(lock=>{return this.updateNode(pathInfo.parentPath,{[pathInfo.key]:null},{tid:tid}).then(result=>{lock.release();return result}).catch(err=>{lock.release();throw err})})}setNode(path,value,options={assert_revision:undefined,tid:undefined}){const pathInfo=PathInfo.get(path);let lock;const tid=options&&options.tid||ID.generate();return this.nodeLocker.lock(path,tid,true,"setNode").then(l=>{lock=l;if(path===""){if(value===null||typeof value!=="object"||value instanceof Array||value instanceof ArrayBuffer||"buffer"in value&&value.buffer instanceof ArrayBuffer){return Promise.reject(new Error(`Invalid value for root node: ${value}`))}return this._writeNodeWithTracking("",value,{merge:false,tid:tid})}if(options&&typeof options.assert_revision!=="undefined"){return this.getNodeInfo(path,{tid:lock.tid}).then(info=>{if(info.revision!==options.assert_revision){throw new NodeRevisionError(`revision '${info.revision}' does not match requested revision '${options.assert_revision}'`)}if(info.address&&info.address.path===path&&!this.valueFitsInline(value)){return this._writeNodeWithTracking(path,value,{merge:false,tid:tid})}else{return lock.moveToParent().then(parentLock=>{lock=parentLock;return this._writeNodeWithTracking(pathInfo.parentPath,{[pathInfo.key]:value},{merge:true,tid:tid})})}})}else{return lock.moveToParent().then(parentLock=>{lock=parentLock;return this.updateNode(pathInfo.parentPath,{[pathInfo.key]:value},{tid:tid})})}}).then(result=>{lock.release();return result}).catch(err=>{lock.release();throw err})}updateNode(path,updates,options={tid:undefined}){if(typeof updates!=="object"){return Promise.reject(new Error(`invalid updates argument`))}const tid=options&&options.tid||ID.generate();let lock;return this.nodeLocker.lock(path,tid,true,"updateNode").then(l=>{lock=l;return this.getNodeInfo(path,{tid:lock.tid})}).then(nodeInfo=>{const pathInfo=PathInfo.get(path);if(nodeInfo.exists&&nodeInfo.address&&nodeInfo.address.path===path){return this._writeNodeWithTracking(path,updates,{merge:true,tid:tid})}else if(nodeInfo.exists){const pathInfo=PathInfo.get(path);return lock.moveToParent().then(parentLock=>{lock=parentLock;return this._writeNodeWithTracking(pathInfo.parentPath,{[pathInfo.key]:value},{merge:true,tid:tid})})}else{return lock.moveToParent().then(parentLock=>{lock=parentLock;return this.updateNode(pathInfo.parentPath,{[pathInfo.key]:updates},{tid:tid})})}}).then(result=>{lock.release();return result}).catch(err=>{lock.release();throw err})}}module.exports={LocalStorageNodeAddress:LocalStorageNodeAddress,LocalStorageNodeInfo:LocalStorageNodeInfo,LocalStorage:LocalStorage,LocalStorageSettings:LocalStorageSettings}},{"./node-info":33,"./node-value-types":35,"./storage":38,"acebase-core":11}],38:[function(require,module,exports){(function(process){const{Utils:Utils,DebugLogger:DebugLogger,PathInfo:PathInfo,ID:ID,PathReference:PathReference,ascii85:ascii85}=require("acebase-core");const{NodeLocker:NodeLocker}=require("./node-lock");const{VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}=require("./node-value-types");const{NodeInfo:NodeInfo}=require("./node-info");const{EventEmitter:EventEmitter}=require("events");const{cloneObject:cloneObject,compareValues:compareValues,getChildValues:getChildValues,encodeString:encodeString}=Utils;const colors=require("colors");class NodeNotFoundError extends Error{}class NodeRevisionError extends Error{}class ClusterSettings{constructor(settings){settings=settings||{};this.enabled=settings.enabled===true;this.isMaster=settings.isMaster===true;this.master=this.isMaster?null:settings.master;this.workers=this.isMaster?settings.workers:null}}class ClusterManager extends EventEmitter{constructor(settings){super();this.settings=new ClusterSettings(settings);if(!settings.enabled){}else if(settings.isMaster){settings.workers.forEach(worker=>{worker.on("message",data=>{const{id:id,request:request}=data;if(typeof request==="object"&&request.type==="ping"){worker.send({id:id,result:"pong"})}else{const reply=result=>{worker.send({id:id,result:result})};const broadcast=msg=>{console.assert(!("id"in msg),"message to broadcast cannot have id property, it will confuse workers because they think it is a reply to their request");settings.workers.forEach(otherWorker=>{if(otherWorker!==worker){otherWorker.send(msg)}})};this.emit("worker_request",{request:request,reply:reply,broadcast:broadcast})}})});this.request=msg=>{throw new Error(`request can only be called by worker processes!`)}}else{const master=settings.master;const requests={};this.request=msg=>{return new Promise((resolve,reject)=>{const id=ID.generate();requests[id]=resolve;master.send({id:id,request:msg})})};master.on("message",data=>{if(typeof data.id!=="undefined"){let resolve=requests[data.id];delete requests[data.id];resolve(data.result)}else{this.emit("master_notification",data)}});this.request({type:"ping"}).then(result=>{console.log(`PING master process result: ${result}`)})}}get isMaster(){return this.settings.isMaster}get enabled(){return this.settings.enabled}}class StorageSettings{constructor(settings){settings=settings||{};this.maxInlineValueSize=typeof settings.maxInlineValueSize==="number"?settings.maxInlineValueSize:50;this.removeVoidProperties=settings.removeVoidProperties===true;this.cluster=new ClusterSettings(settings.cluster);this.path=settings.path||".";if(this.path.endsWith("/")){this.path=this.path.slice(0,-1)}this.logLevel=settings.logLevel||"log";this.info=settings.info||"realtime database"}}class Storage extends EventEmitter{constructor(name,settings){super();this.name=name;this.settings=settings;this.debug=new DebugLogger(settings.logLevel,`[${name}]`);colors.setTheme({art:["magenta","bold"],intro:["dim"]});const logo=" ___ ______ ".art+"\n"+" / _ \\ | ___ \\ ".art+"\n"+" / /_\\ \\ ___ ___| |_/ / __ _ ___ ___ ".art+"\n"+" | _ |/ __/ _ \\ ___ \\/ _` / __|/ _ \\".art+"\n"+" | | | | (_| __/ |_/ / (_| \\__ \\ __/".art+"\n"+" \\_| |_/\\___\\___\\____/ \\__,_|___/\\___|".art+"\n"+(settings.info?"".padStart(40-settings.info.length," ")+settings.info.magenta+"\n":"");this.debug.write(logo);this.nodeCache={find(path){return null},update(path,info){}};this.nodeLocker=new NodeLocker;this.cluster=new ClusterManager(settings.cluster);const{DataIndex:DataIndex,ArrayIndex:ArrayIndex,FullTextIndex:FullTextIndex,GeoIndex:GeoIndex}=require("./data-index");const _indexes=[];const storage=this;this.indexes={create(path,key,options={rebuild:false,type:undefined,include:undefined}){path=path.replace(/\/\*$/,"");const rebuild=options&&options.rebuild===true;const indexType=options&&options.type||"normal";let includeKeys=options&&options.include||[];if(typeof includeKeys==="string"){includeKeys=[includeKeys]}const existingIndex=_indexes.find(index=>index.path===path&&index.key===key&&index.type===indexType&&index.includeKeys.length===includeKeys.length&&index.includeKeys.every((key,index)=>includeKeys[index]===key));if(existingIndex&&rebuild!==true){storage.debug.log(`Index on "/${path}/*/${key}" already exists`.inverse);return Promise.resolve(existingIndex)}const index=existingIndex||(()=>{switch(indexType){case"array":return new ArrayIndex(storage,path,key,{include:options.include,config:options.config});case"fulltext":return new FullTextIndex(storage,path,key,{include:options.include,config:options.config});case"geo":return new GeoIndex(storage,path,key,{include:options.include,config:options.config});default:return new DataIndex(storage,path,key,{include:options.include,config:options.config})}})();if(!existingIndex){_indexes.push(index)}return index.build().then(()=>{return index}).catch(err=>{storage.debug.error(`Index build on "/${path}/*/${key}" failed: ${err.message} (code: ${err.code})`.red);if(!existingIndex){_indexes.splice(_indexes.indexOf(index),1)}throw err})},get(path,key=null){return _indexes.filter(index=>index.path===path&&(key===null||key===index.key))},getAll(targetPath,options={parentPaths:true,childPaths:true}){const pathKeys=PathInfo.getPathKeys(targetPath);return _indexes.filter(index=>{const indexKeys=PathInfo.getPathKeys(index.path+"/*");if(options.parentPaths&&indexKeys.every((key,i)=>{return key==="*"||pathKeys[i]===key})&&[index.key].concat(...index.includeKeys).includes(pathKeys[indexKeys.length])){return true}else if(indexKeys.length{return[key,"*"].includes(indexKeys[i])})})},list(){return _indexes.slice()},load(){_indexes.splice(0);const pfs=require("./promise-fs");if(!pfs||!pfs.readdir){return Promise.resolve()}return pfs.readdir(`${storage.settings.path}/${storage.name}.acebase`).then(files=>{const promises=[];files.forEach(fileName=>{if(fileName.endsWith(".idx")){const p=DataIndex.readFromFile(storage,fileName).then(index=>{_indexes.push(index)}).catch(err=>{storage.debug.error(err)});promises.push(p)}});return Promise.all(promises)}).catch(err=>{storage.debug.error(err)})}};const _subs={};const _supportedEvents=["value","child_added","child_changed","child_removed"];_supportedEvents.push(..._supportedEvents.map(event=>`notify_${event}`));this.subscriptions={add(path,type,callback){if(_supportedEvents.indexOf(type)<0){throw new TypeError(`Invalid event type "${type}"`)}let pathSubs=_subs[path];if(!pathSubs){pathSubs=_subs[path]=[]}pathSubs.push({created:Date.now(),type:type,callback:callback})},remove(path,type=undefined,callback=undefined){let pathSubs=_subs[path];if(!pathSubs){return}while(true){const i=pathSubs.findIndex(ps=>type?ps.type===type:true&&callback?ps.callback===callback:true);if(i<0){break}pathSubs.splice(i,1)}},hasValueSubscribersForPath(path){const valueNeeded=this.getValueSubscribersForPath(path);return!!valueNeeded},getValueSubscribersForPath(path){const pathInfo=new PathInfo(path);const valueSubscribers=[];Object.keys(_subs).forEach(subscriptionPath=>{if(pathInfo.equals(subscriptionPath)||pathInfo.isDescendantOf(subscriptionPath)){let pathSubs=_subs[subscriptionPath];const eventPath=PathInfo.fillVariables(subscriptionPath,path);pathSubs.forEach(sub=>{let dataPath=null;if(sub.type==="value"||sub.type==="notify_value"){dataPath=eventPath}else if((sub.type==="child_changed"||sub.type==="notify_child_changed")&&path!==eventPath){let childKey=PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}else if(["child_added","child_removed","notify_child_added","notify_child_removed"].includes(sub.type)&&pathInfo.isChildOf(eventPath)){let childKey=PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}if(dataPath!==null&&valueSubscribers.findIndex(s=>s.type===sub.type&&s.path===eventPath)<0){valueSubscribers.push({type:sub.type,eventPath:eventPath,dataPath:dataPath,subscriptionPath:subscriptionPath})}})}});return valueSubscribers},getAllSubscribersForPath(path){const pathInfo=PathInfo.get(path);const subscribers=[];Object.keys(_subs).forEach(subscriptionPath=>{if(pathInfo.equals(subscriptionPath)||pathInfo.isDescendantOf(subscriptionPath)||pathInfo.isAncestorOf(subscriptionPath)){let pathSubs=_subs[subscriptionPath];const eventPath=PathInfo.fillVariables(subscriptionPath,path);pathSubs.forEach(sub=>{let dataPath=null;if(sub.type==="value"||sub.type==="notify_value"){dataPath=eventPath}else if(sub.type==="child_changed"||sub.type==="notify_child_changed"){let childKey=path===eventPath||pathInfo.isAncestorOf(eventPath)?"*":PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}else if(["child_added","child_removed","notify_child_added","notify_child_removed"].includes(sub.type)&&(pathInfo.isChildOf(eventPath)||path===eventPath||pathInfo.isAncestorOf(eventPath))){let childKey=path===eventPath||pathInfo.isAncestorOf(eventPath)?"*":PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}if(dataPath!==null){subscribers.push({type:sub.type,eventPath:eventPath,dataPath:dataPath,subscriptionPath:subscriptionPath})}})}});return subscribers},trigger(event,path,dataPath,oldValue,newValue){const pathSubscriptions=_subs[path]||[];pathSubscriptions.filter(sub=>sub.type===event).forEach(sub=>{sub.callback(null,dataPath,newValue,oldValue)})}}}valueFitsInline(value){const encoding="utf8";if(typeof value==="number"||typeof value==="boolean"||value instanceof Date){return true}else if(typeof value==="string"){if(value.length>this.settings.maxInlineValueSize){return false}const encoded=encodeString(value);return encoded.lengththis.settings.maxInlineValueSize){return false}const encoded=encodeString(value.path);return encoded.length0){hasValueSubscribers=true;let eventPaths=valueSubscribers.map(sub=>{return{path:sub.dataPath,keys:PathInfo.getPathKeys(sub.dataPath)}}).sort((a,b)=>{if(a.keys.lengthb.keys.length)return 1;return 0});let first=eventPaths[0];topEventPath=first.path;if(valueSubscribers.filter(sub=>sub.dataPath===topEventPath).every(sub=>sub.type.startsWith("notify_"))){hasValueSubscribers=false}topEventPath=PathInfo.fillVariables(topEventPath,path)}const writeNode=()=>{if(typeof options._customWriteFunction==="function"){return options._customWriteFunction()}return this._writeNode(path,value,options)};const indexes=this.indexes.getAll(path,{childPaths:true,parentPaths:true}).map(index=>({index:index,keys:PathInfo.getPathKeys(index.path)})).sort((a,b)=>{if(a.keys.lengthb.keys.length){return 1}return 0}).map(obj=>obj.index);if(eventSubscriptions.length===0&&indexes.length===0){return writeNode()}let keysFilter=[];if(indexes.length>0){indexes.sort((a,b)=>{if(typeof a._pathKeys==="undefined"){a._pathKeys=PathInfo.getPathKeys(a.path)}if(typeof b._pathKeys==="undefined"){b._pathKeys=PathInfo.getPathKeys(b.path)}if(a._pathKeys.lengthb._pathKeys.length)return 1;return 0});const topIndex=indexes[0];let topIndexPath=topIndex.path===path?path:PathInfo.fillVariables(`${topIndex.path}/*`,path);if(topIndexPath.lengthindex.path===topIndex.path).forEach(index=>{let keys=[index.key].concat(index.includeKeys);keys.forEach(key=>!keysFilter.includes(key)&&keysFilter.push(key))})}}if(!hasValueSubscribers&&options.merge===true&&keysFilter.length===0){keysFilter=Object.keys(value);if(topEventPath!==path){let trailPath=path.slice(topEventPath.length);keysFilter=keysFilter.map(key=>`${trailPath}/${key}`)}}return this.getNodeInfo(topEventPath,{tid:tid}).then(eventNodeInfo=>{if(!eventNodeInfo.exists){return null}let valueOptions={tid:tid};if(keysFilter.length>0){valueOptions.include=keysFilter}if(topEventPath===""&&typeof valueOptions.include==="undefined"){this.debug.warn(`WARNING: One or more value event listeners on the root node are causing the entire database value to be read to facilitate change tracking. Using "value", "notify_value", "child_changed" and "notify_child_changed" events on the root node are a bad practice because of the significant performance impact`)}return this.getNodeValue(topEventPath,valueOptions)}).then(currentValue=>{topEventData=currentValue;return writeNode()}).then(result=>{let newTopEventData=cloneObject(topEventData);if(newTopEventData===null){newTopEventData=path===topEventPath?value:{}}let modifiedData=newTopEventData;if(path!==topEventPath){let trailPath=path.slice(topEventPath.length).replace(/^\//,"");let trailKeys=PathInfo.getPathKeys(trailPath);while(trailKeys.length>0){let childKey=trailKeys.shift();if(!options.merge&&trailKeys.length===0){modifiedData[childKey]=value}else{if(!(childKey in modifiedData)){modifiedData[childKey]={}}modifiedData=modifiedData[childKey]}}}if(options.merge){Object.keys(value).forEach(key=>{let newValue=value[key];if(newValue!==null){modifiedData[key]=newValue}else{delete modifiedData[key]}})}else if(path===topEventPath){newTopEventData=modifiedData=value}const indexUpdates=[];indexes.map(index=>({index:index,keys:PathInfo.getPathKeys(index.path)})).sort((a,b)=>{if(a.keys.lengthb.keys.length){return-1}return 0}).forEach(({index:index})=>{let pathKeys=PathInfo.getPathKeys(topEventPath);let indexPathKeys=PathInfo.getPathKeys(index.path+"/*");let trailKeys=indexPathKeys.slice(pathKeys.length);let oldValue=topEventData;let newValue=newTopEventData;if(trailKeys.length===0){console.assert(pathKeys.length===indexPathKeys.length,"check logic");const p=index.handleRecordUpdate(topEventPath,oldValue,newValue);indexUpdates.push(p);return}const getAllIndexUpdates=(path,oldValue,newValue)=>{if(oldValue===null&&newValue===null){return[]}let pathKeys=PathInfo.getPathKeys(path);let indexPathKeys=PathInfo.getPathKeys(index.path+"/*");let trailKeys=indexPathKeys.slice(pathKeys.length);if(trailKeys.length===0){console.assert(pathKeys.length===indexPathKeys.length,"check logic");return[{path:path,oldValue:oldValue,newValue:newValue}]}let results=[];let trailPath="";while(trailKeys.length>0){let subKey=trailKeys.shift();if(subKey==="*"){let allKeys=oldValue===null?[]:Object.keys(oldValue);newValue!==null&&Object.keys(newValue).forEach(key=>{if(allKeys.indexOf(key)<0){allKeys.push(key)}});allKeys.forEach(key=>{let childPath=PathInfo.getChildPath(trailPath,key);let childValues=getChildValues(key,oldValue,newValue);let subTrailPath=PathInfo.getChildPath(path,childPath);let childResults=getAllIndexUpdates(subTrailPath,childValues.oldValue,childValues.newValue);results=results.concat(childResults)});break}else{let values=getChildValues(subKey,oldValue,newValue);oldValue=values.oldValue;newValue=values.newValue;if(oldValue===null&&newValue===null){break}trailPath=PathInfo.getChildPath(trailPath,subKey)}}return results};let results=getAllIndexUpdates(topEventPath,oldValue,newValue);results.forEach(result=>{const p=index.handleRecordUpdate(result.path,result.oldValue,result.newValue);indexUpdates.push(p)})});const callSubscriberWithValues=(sub,oldValue,newValue,variables=[])=>{let trigger=true;let type=sub.type;if(type.startsWith("notify_")){type=type.slice("notify_".length)}if(type==="child_changed"&&(oldValue===null||newValue===null)){trigger=false}else if(type==="value"||type==="child_changed"){let changes=compareValues(oldValue,newValue);trigger=changes!=="identical"}else if(type==="child_added"){trigger=oldValue===null&&newValue!==null}else if(type==="child_removed"){trigger=oldValue!==null&&newValue===null}let dataPath=sub.dataPath;variables.forEach((variable,i)=>{const safeVarName=variable.name==="*"?"\\*":variable.name.replace("$","\\$");dataPath=dataPath.replace(new RegExp(`(^|/)${safeVarName}([/[]|$)`),`$1${variable.value}$2`)});trigger&&this.subscriptions.trigger(sub.type,sub.subscriptionPath,dataPath,oldValue,newValue)};const triggerAllEvents=()=>{eventSubscriptions.map(sub=>{const keys=PathInfo.getPathKeys(sub.dataPath);return{sub:sub,keys:keys}}).sort((a,b)=>{if(a.keys.lengthb.keys.length){return-1}return 0}).forEach(({sub:sub})=>{const process=(currentPath,oldValue,newValue,variables=[])=>{let trailPath=sub.dataPath.slice(currentPath.length).replace(/^\//,"");let trailKeys=PathInfo.getPathKeys(trailPath);while(trailKeys.length>0){let subKey=trailKeys.shift();if(typeof subKey==="string"&&(subKey==="*"||subKey[0]==="$")){let allKeys=oldValue===null?[]:Object.keys(oldValue);newValue!==null&&Object.keys(newValue).forEach(key=>{if(allKeys.indexOf(key)<0){allKeys.push(key)}});allKeys.forEach(key=>{const childValues=getChildValues(key,oldValue,newValue);const vars=variables.concat({name:subKey,value:key});if(trailKeys.length===0){callSubscriberWithValues(sub,childValues.oldValue,childValues.newValue,vars)}else{process(`${currentPath}/${subKey}`,childValues.oldValue,childValues.newValue,vars)}});return}else{currentPath=PathInfo.getChildPath(currentPath,subKey);let childValues=getChildValues(subKey,oldValue,newValue);oldValue=childValues.oldValue;newValue=childValues.newValue}}callSubscriberWithValues(sub,oldValue,newValue,variables)};process(topEventPath,topEventData,newTopEventData)})};if(options.waitForIndexUpdates===false){indexUpdates.splice(0)}return Promise.all(indexUpdates).then(()=>{process.nextTick(triggerAllEvents);return result})})}getChildren(path,options={keyFilter:undefined,tid:undefined}){throw new Error(`This method must be implemented by subclass`)}getNodeValue(path,options={include:undefined,exclude:undefined,child_objects:true,tid:undefined}){return this.getNode(path,options).then(node=>{return node.value})}getNode(path,options={include:undefined,exclude:undefined,child_objects:true,tid:undefined}){throw new Error(`This method must be implemented by subclass`)}getNodeInfo(path,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}removeNode(path,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}setNode(path,value,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}updateNode(path,updates,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}transactNode(path,callback,options={no_lock:false}){let checkRevision;const tid=ID.generate();const lockPromise=options&&options.no_lock===true?Promise.resolve({tid:tid,release(){}}):this.nodeLocker.lock(path,tid,true,"transactNode");return lockPromise.then(lock=>{let changed=false,changeCallback=(err,path)=>{changed=true};if(options&&options.no_lock){this.subscriptions.add(path,"notify_value",changeCallback)}return this.getNode(path,{tid:tid}).then(node=>{checkRevision=node.revision;let newValue;try{newValue=callback(node.value)}catch(err){this.debug.error(`Error in transaction callback: ${err.message}`)}if(newValue instanceof Promise){return newValue.catch(err=>{this.debug.error(`Error in transaction callback: ${err.message}`)})}return newValue}).then(newValue=>{if(typeof newValue==="undefined"){return}if(options&&options.no_lock){this.subscriptions.remove(path,"notify_value",changeCallback)}if(changed){return Promise.reject(new NodeRevisionError(`Node changed`))}return this.setNode(path,newValue,{assert_revision:checkRevision,tid:lock.tid})}).then(result=>{lock.release();return result}).catch(err=>{lock.release();if(err instanceof NodeRevisionError){console.warn(`node value changed, running again. Error: ${err.message}`);return this.transactNode(path,callback,options)}else{throw err}})})}matchNode(path,criteria,options={tid:undefined}){const tid=options&&options.tid||ID.generate();const checkNode=(path,criteria)=>{if(criteria.length===0){return Promise.resolve(true)}const criteriaKeys=criteria.reduce((keys,cr)=>{if(keys.indexOf(cr.key)<0){keys.push(cr.key)}return keys},[]);const unseenKeys=criteriaKeys.slice();let isMatch=true;let delayedMatchPromises=[];return this.getChildren(path,{tid:tid}).next(childInfo=>{unseenKeys.includes(childInfo.key)&&unseenKeys.splice(unseenKeys.indexOf(childInfo.key),1);const keyCriteria=criteria.filter(cr=>cr.key===childInfo.key).map(cr=>({op:cr.op,compare:cr.compare}));const result=checkChild(childInfo,keyCriteria);isMatch=result.isMatch;delayedMatchPromises.push(...result.promises);if(!isMatch||unseenKeys.length===0){return false}}).then(()=>{if(isMatch){return Promise.all(delayedMatchPromises).then(results=>{isMatch=results.every(res=>res.isMatch)})}}).then(()=>{if(!isMatch){return false}isMatch=unseenKeys.every(key=>{const child=new NodeInfo({key:key,exists:false});const keyCriteria=criteria.filter(cr=>cr.key===key).map(cr=>({op:cr.op,compare:cr.compare}));const result=checkChild(child,keyCriteria);return result.isMatch});return isMatch}).catch(err=>{this.debug.error(`Error matching on "${path}": `,err);throw err})};const checkChild=(child,criteria)=>{const promises=[];const isMatch=criteria.every(f=>{let proceed=true;if(f.op==="!exists"||f.op==="=="&&(f.compare===null||f.compare===undefined)){proceed=!child.exists}else if(f.op==="exists"||f.op==="!="&&(f.compare===null||f.compare===undefined)){proceed=child.exists}else if(!child.exists){proceed=false}else{if(child.address){if(child.valueType===VALUE_TYPES.OBJECT&&["has","!has"].indexOf(f.op)>=0){const op=f.op==="has"?"exists":"!exists";const p=checkNode(child.path,[{key:f.compare,op:op}]).then(isMatch=>{return{key:child.key,isMatch:isMatch}});promises.push(p);proceed=true}else if(child.valueType===VALUE_TYPES.ARRAY&&["contains","!contains"].indexOf(f.op)>=0){const p=this.getNodeValue(child.path,{tid:tid}).then(arr=>{const isMatch=f.op==="contains"?f.compare instanceof Array?f.compare.every(val=>arr.includes(val)):arr.includes(f.compare):f.compare instanceof Array?!f.compare.some(val=>arr.includes(val)):!arr.includes(f.compare);return{key:child.key,isMatch:isMatch}});promises.push(p);proceed=true}else if(child.valueType===VALUE_TYPES.STRING){const p=this.getNodeValue(child.path,{tid:tid}).then(val=>{return{key:child.key,isMatch:this.test(val,f.op,f.compare)}});promises.push(p);proceed=true}else{proceed=false}}else if(child.type===VALUE_TYPES.OBJECT&&["has","!has"].indexOf(f.op)>=0){const has=f.compare in child.value;proceed=has&&f.op==="has"||!has&&f.op==="!has"}else if(child.type===VALUE_TYPES.ARRAY&&["contains","!contains"].indexOf(f.op)>=0){const contains=child.value.indexOf(f.compare)>=0;proceed=contains&&f.op==="contains"||!contains&&f.op==="!contains"}else{const ret=this.test(child.value,f.op,f.compare);if(ret instanceof Promise){promises.push(ret);ret=true}proceed=ret}}return proceed});return{isMatch:isMatch,promises:promises}};return checkNode(path,criteria)}test(val,op,compare){if(op==="<"){return val"){return val>compare}if(op===">="){return val>=compare}if(op==="in"){return compare.indexOf(val)>=0}if(op==="!in"){return compare.indexOf(val)<0}if(op==="like"||op==="!like"){const pattern="^"+compare.replace(/[-[\]{}()+.,\\^$|#\s]/g,"\\$&").replace(/\?/g,".").replace(/\*/g,".*?")+"$";const re=new RegExp(pattern,"i");const isMatch=re.test(val.toString());return op==="like"?isMatch:!isMatch}if(op==="matches"){return compare.test(val.toString())}if(op==="!matches"){return!compare.test(val.toString())}if(op==="between"){return val>=compare[0]&&val<=compare[1]}if(op==="!between"){return valcompare[1]}if(op==="has"||op==="!has"){const has=typeof val==="object"&&compare in val;return op==="has"?has:!has}if(op==="contains"||op==="!contains"){const includes=typeof val==="object"&&val instanceof Array&&val.includes(compare);return op==="contains"?includes:!includes}return false}exportNode(path,stream,options={format:"json"}){if(options&&options.format!=="json"){throw new Error(`Only json output is currently supported`)}const stringifyValue=(type,val)=>{const escape=str=>str.replace(/\\/i,"\\\\").replace(/"/g,'\\"');if(type===VALUE_TYPES.DATETIME){val=`"${val.toISOString()}"`}else if(type===VALUE_TYPES.STRING){val=`"${escape(val)}"`}else if(type===VALUE_TYPES.ARRAY){val=`[]`}else if(type===VALUE_TYPES.OBJECT){val=`{}`}else if(type===VALUE_TYPES.BINARY){val=`"${escape(ascii85.encode(val))}"`}else if(type===VALUE_TYPES.REFERENCE){val=`"${val.path}"`}return val};const queue=[];let outputCount=0;let objStart="",objEnd="";const buffer={output:"",enable:false,promise:null};return this.getNodeInfo(path).then(nodeInfo=>{if(!nodeInfo.exists){stream.write("null")}else if(nodeInfo.type===VALUE_TYPES.OBJECT){objStart="{";objEnd="}"}else if(nodeInfo.type===VALUE_TYPES.ARRAY){objStart="{";objEnd="}"}else{return this.getNodeValue(path).then(value=>{const val=stringifyValue(nodeInfo.type,value);return stream.write(val)})}let p=Promise.resolve();if(objStart){p=stream.write(objStart);if(!(p instanceof Promise)){p=Promise.resolve()}}return p.then(()=>{return this.getChildren(path).next(childInfo=>{if(childInfo.address){queue.push(childInfo)}else{const val=stringifyValue(childInfo.type,childInfo.value);const comma=outputCount>0?",":"";const key=typeof childInfo.index==="number"?`"${childInfo.index}"`:`"${childInfo.key}"`;const output=`${comma}${key}:${val}`;outputCount++;if(buffer.enable){buffer.output+=output}else{const flush=output=>{const p=stream.write(output);if(p instanceof Promise){buffer.enable=true;buffer.promise=p.then(()=>{const buffered=buffer.output;buffer.enable=false;buffer.output="";buffer.promise=null;if(buffered.length>0){return flush(buffered)}});return buffer.promise}};flush(output)}}})})}).then(()=>{return buffer.promise}).then(()=>{const next=()=>{if(queue.length===0){return}const childInfo=queue.shift();const comma=outputCount>0?",":"";const key=typeof childInfo.index==="number"?`"${childInfo.index}"`:`"${childInfo.key}"`;let p=stream.write(`${comma}${key}:`);outputCount++;if(!(p instanceof Promise)){p=Promise.resolve(p)}return p.then(()=>{return this.exportNode(childInfo.address.path,stream)}).then(()=>{return next()})};return next()}).then(()=>{if(objEnd){return stream.write(objEnd)}})}}module.exports={Storage:Storage,StorageSettings:StorageSettings,NodeNotFoundError:NodeNotFoundError,NodeRevisionError:NodeRevisionError}}).call(this,require("_process"))},{"./data-index":39,"./node-info":33,"./node-lock":34,"./node-value-types":35,"./promise-fs":39,_process:43,"acebase-core":11,colors:22,events:40}],39:[function(require,module,exports){},{}],40:[function(require,module,exports){var objectCreate=Object.create||objectCreatePolyfill;var objectKeys=Object.keys||objectKeysPolyfill;var bind=Function.prototype.bind||functionBindPolyfill;function EventEmitter(){if(!this._events||!Object.prototype.hasOwnProperty.call(this,"_events")){this._events=objectCreate(null);this._eventsCount=0}this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;var defaultMaxListeners=10;var hasDefineProperty;try{var o={};if(Object.defineProperty)Object.defineProperty(o,"x",{value:0});hasDefineProperty=o.x===0}catch(err){hasDefineProperty=false}if(hasDefineProperty){Object.defineProperty(EventEmitter,"defaultMaxListeners",{enumerable:true,get:function(){return defaultMaxListeners},set:function(arg){if(typeof arg!=="number"||arg<0||arg!==arg)throw new TypeError('"defaultMaxListeners" must be a positive number');defaultMaxListeners=arg}})}else{EventEmitter.defaultMaxListeners=defaultMaxListeners}EventEmitter.prototype.setMaxListeners=function setMaxListeners(n){if(typeof n!=="number"||n<0||isNaN(n))throw new TypeError('"n" argument must be a positive number');this._maxListeners=n;return this};function $getMaxListeners(that){if(that._maxListeners===undefined)return EventEmitter.defaultMaxListeners;return that._maxListeners}EventEmitter.prototype.getMaxListeners=function getMaxListeners(){return $getMaxListeners(this)};function emitNone(handler,isFn,self){if(isFn)handler.call(self);else{var len=handler.length;var listeners=arrayClone(handler,len);for(var i=0;i1)er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Unhandled "error" event. ('+er+")");err.context=er;throw err}return false}handler=events[type];if(!handler)return false;var isFn=typeof handler==="function";len=arguments.length;switch(len){case 1:emitNone(handler,isFn,this);break;case 2:emitOne(handler,isFn,this,arguments[1]);break;case 3:emitTwo(handler,isFn,this,arguments[1],arguments[2]);break;case 4:emitThree(handler,isFn,this,arguments[1],arguments[2],arguments[3]);break;default:args=new Array(len-1);for(i=1;i0&&existing.length>m){existing.warned=true;var w=new Error("Possible EventEmitter memory leak detected. "+existing.length+' "'+String(type)+'" listeners '+"added. Use emitter.setMaxListeners() to "+"increase limit.");w.name="MaxListenersExceededWarning";w.emitter=target;w.type=type;w.count=existing.length;if(typeof console==="object"&&console.warn){console.warn("%s: %s",w.name,w.message)}}}}return target}EventEmitter.prototype.addListener=function addListener(type,listener){return _addListener(this,type,listener,false)};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.prependListener=function prependListener(type,listener){return _addListener(this,type,listener,true)};function onceWrapper(){if(!this.fired){this.target.removeListener(this.type,this.wrapFn);this.fired=true;switch(arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:var args=new Array(arguments.length);for(var i=0;i=0;i--){if(list[i]===listener||list[i].listener===listener){originalListener=list[i].listener;position=i;break}}if(position<0)return this;if(position===0)list.shift();else spliceOne(list,position);if(list.length===1)events[type]=list[0];if(events.removeListener)this.emit("removeListener",type,originalListener||listener)}return this};EventEmitter.prototype.removeAllListeners=function removeAllListeners(type){var listeners,events,i;events=this._events;if(!events)return this;if(!events.removeListener){if(arguments.length===0){this._events=objectCreate(null);this._eventsCount=0}else if(events[type]){if(--this._eventsCount===0)this._events=objectCreate(null);else delete events[type]}return this}if(arguments.length===0){var keys=objectKeys(events);var key;for(i=0;i=0;i--){this.removeListener(type,listeners[i])}}return this};function _listeners(target,type,unwrap){var events=target._events;if(!events)return[];var evlistener=events[type];if(!evlistener)return[];if(typeof evlistener==="function")return unwrap?[evlistener.listener||evlistener]:[evlistener];return unwrap?unwrapListeners(evlistener):arrayClone(evlistener,evlistener.length)}EventEmitter.prototype.listeners=function listeners(type){return _listeners(this,type,true)};EventEmitter.prototype.rawListeners=function rawListeners(type){return _listeners(this,type,false)};EventEmitter.listenerCount=function(emitter,type){if(typeof emitter.listenerCount==="function"){return emitter.listenerCount(type)}else{return listenerCount.call(emitter,type)}};EventEmitter.prototype.listenerCount=listenerCount;function listenerCount(type){var events=this._events;if(events){var evlistener=events[type];if(typeof evlistener==="function"){return 1}else if(evlistener){return evlistener.length}}return 0}EventEmitter.prototype.eventNames=function eventNames(){return this._eventsCount>0?Reflect.ownKeys(this._events):[]};function spliceOne(list,index){for(var i=index,k=i+1,n=list.length;k1){for(var i=1;i=len)return x;switch(x){case"%s":return String(args[i++]);case"%d":return Number(args[i++]);case"%j":try{return JSON.stringify(args[i++])}catch(_){return"[Circular]"}default:return x}}));for(var x=args[i];i=3)ctx.depth=arguments[2];if(arguments.length>=4)ctx.colors=arguments[3];if(isBoolean(opts)){ctx.showHidden=opts}else if(opts){exports._extend(ctx,opts)}if(isUndefined(ctx.showHidden))ctx.showHidden=false;if(isUndefined(ctx.depth))ctx.depth=2;if(isUndefined(ctx.colors))ctx.colors=false;if(isUndefined(ctx.customInspect))ctx.customInspect=true;if(ctx.colors)ctx.stylize=stylizeWithColor;return formatValue(ctx,obj,ctx.depth)}exports.inspect=inspect;inspect.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]};inspect.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"};function stylizeWithColor(str,styleType){var style=inspect.styles[styleType];if(style){return"["+inspect.colors[style][0]+"m"+str+"["+inspect.colors[style][1]+"m"}else{return str}}function stylizeNoColor(str,styleType){return str}function arrayToHash(array){var hash={};array.forEach((function(val,idx){hash[val]=true}));return hash}function formatValue(ctx,value,recurseTimes){if(ctx.customInspect&&value&&isFunction(value.inspect)&&value.inspect!==exports.inspect&&!(value.constructor&&value.constructor.prototype===value)){var ret=value.inspect(recurseTimes,ctx);if(!isString(ret)){ret=formatValue(ctx,ret,recurseTimes)}return ret}var primitive=formatPrimitive(ctx,value);if(primitive){return primitive}var keys=Object.keys(value);var visibleKeys=arrayToHash(keys);if(ctx.showHidden){keys=Object.getOwnPropertyNames(value)}if(isError(value)&&(keys.indexOf("message")>=0||keys.indexOf("description")>=0)){return formatError(value)}if(keys.length===0){if(isFunction(value)){var name=value.name?": "+value.name:"";return ctx.stylize("[Function"+name+"]","special")}if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}if(isDate(value)){return ctx.stylize(Date.prototype.toString.call(value),"date")}if(isError(value)){return formatError(value)}}var base="",array=false,braces=["{","}"];if(isArray(value)){array=true;braces=["[","]"]}if(isFunction(value)){var n=value.name?": "+value.name:"";base=" [Function"+n+"]"}if(isRegExp(value)){base=" "+RegExp.prototype.toString.call(value)}if(isDate(value)){base=" "+Date.prototype.toUTCString.call(value)}if(isError(value)){base=" "+formatError(value)}if(keys.length===0&&(!array||value.length==0)){return braces[0]+base+braces[1]}if(recurseTimes<0){if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}else{return ctx.stylize("[Object]","special")}}ctx.seen.push(value);var output;if(array){output=formatArray(ctx,value,recurseTimes,visibleKeys,keys)}else{output=keys.map((function(key){return formatProperty(ctx,value,recurseTimes,visibleKeys,key,array)}))}ctx.seen.pop();return reduceToSingleString(output,base,braces)}function formatPrimitive(ctx,value){if(isUndefined(value))return ctx.stylize("undefined","undefined");if(isString(value)){var simple="'"+JSON.stringify(value).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return ctx.stylize(simple,"string")}if(isNumber(value))return ctx.stylize(""+value,"number");if(isBoolean(value))return ctx.stylize(""+value,"boolean");if(isNull(value))return ctx.stylize("null","null")}function formatError(value){return"["+Error.prototype.toString.call(value)+"]"}function formatArray(ctx,value,recurseTimes,visibleKeys,keys){var output=[];for(var i=0,l=value.length;i-1){if(array){str=str.split("\n").map((function(line){return" "+line})).join("\n").substr(2)}else{str="\n"+str.split("\n").map((function(line){return" "+line})).join("\n")}}}else{str=ctx.stylize("[Circular]","special")}}if(isUndefined(name)){if(array&&key.match(/^\d+$/)){return str}name=JSON.stringify(""+key);if(name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)){name=name.substr(1,name.length-2);name=ctx.stylize(name,"name")}else{name=name.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'");name=ctx.stylize(name,"string")}}return name+": "+str}function reduceToSingleString(output,base,braces){var numLinesEst=0;var length=output.reduce((function(prev,cur){numLinesEst++;if(cur.indexOf("\n")>=0)numLinesEst++;return prev+cur.replace(/\u001b\[\d\d?m/g,"").length+1}),0);if(length>60){return braces[0]+(base===""?"":base+"\n ")+" "+output.join(",\n ")+" "+braces[1]}return braces[0]+base+" "+output.join(", ")+" "+braces[1]}function isArray(ar){return Array.isArray(ar)}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return isObject(re)&&objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return isObject(d)&&objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return isObject(e)&&(objectToString(e)==="[object Error]"||e instanceof Error)}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=require("./support/isBuffer");function objectToString(o){return Object.prototype.toString.call(o)}function pad(n){return n<10?"0"+n.toString(10):n.toString(10)}var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function timestamp(){var d=new Date;var time=[pad(d.getHours()),pad(d.getMinutes()),pad(d.getSeconds())].join(":");return[d.getDate(),months[d.getMonth()],time].join(" ")}exports.log=function(){console.log("%s - %s",timestamp(),exports.format.apply(exports,arguments))};exports.inherits=require("inherits");exports._extend=function(origin,add){if(!add||!isObject(add))return origin;var keys=Object.keys(add);var i=keys.length;while(i--){origin[keys[i]]=add[keys[i]]}return origin};function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}}).call(this,require("_process"),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./support/isBuffer":44,_process:43,inherits:41}]},{},[32]); \ No newline at end of file +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,(function(r){var n=e[i][1][r];return o(n||r)}),p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i=7&&stringLength<=10)return true;return false};cuid.fingerprint=fingerprint;module.exports=cuid},{"./lib/fingerprint.js":2,"./lib/pad.js":3}],2:[function(require,module,exports){var pad=require("./pad.js");var env=typeof window==="object"?window:self;var globalCount=Object.keys(env).length;var mimeTypesLength=navigator.mimeTypes?navigator.mimeTypes.length:0;var clientId=pad((mimeTypesLength+navigator.userAgent.length).toString(36)+globalCount.toString(36),4);module.exports=function fingerprint(){return clientId}},{"./pad.js":3}],3:[function(require,module,exports){module.exports=function pad(num,size){var s="000000000"+num;return s.substr(s.length-size)}},{}],4:[function(require,module,exports){const{EventEmitter:EventEmitter}=require("events");const{DataReference:DataReference,DataReferenceQuery:DataReferenceQuery}=require("./data-reference");const{TypeMappings:TypeMappings}=require("./type-mappings");class AceBaseSettings{constructor(options){this.logLevel=options.logLevel||"log"}}class AceBaseBase extends EventEmitter{constructor(dbname,options){super();if(!options){options={}}this.once("ready",()=>{this._ready=true});this.types=new TypeMappings(this)}ready(callback=undefined){if(this._ready===true){callback&&callback();return Promise.resolve()}else{let resolve;const promise=new Promise(res=>resolve=res);this.on("ready",()=>{resolve();callback&&callback()});return promise}}get isReady(){return this._ready===true}ref(path){return new DataReference(this,path)}get root(){return this.ref("")}query(path){const ref=new DataReference(this,path);return new DataReferenceQuery(ref)}get indexes(){return{get:()=>{return this.api.getIndexes()},create:(path,key,options)=>{return this.api.createIndex(path,key,options)}}}}module.exports={AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings}},{"./data-reference":7,"./type-mappings":16,events:40}],5:[function(require,module,exports){class Api{stats(options=undefined){}subscribe(path,event,callback){}unsubscribe(path,event,callback){}update(path,updates){}set(path,value){}get(path,options){}exists(path){}query(path,query,options){}createIndex(path,key){}getIndexes(){}}module.exports={Api:Api}},{}],6:[function(require,module,exports){const c=function(input,length,result){var i,j,n,b=[0,0,0,0,0];for(i=0;i";return ret},decode:function(input){if(!input.startsWith("<~")||!input.endsWith("~>")){throw new Error("Invalid input string")}input=input.substr(2,input.length-4);var n=input.length,r=[],b=[0,0,0,0,0],i,j,t,x,y,d;for(i=0;i>>=8;y=t&255;t>>>=8;r.push(t>>>8,t&255,y,x);for(j=d;j<5;++j,r.pop());i+=4}const data=new Uint8Array(r);return data.buffer.slice(data.byteOffset,data.byteOffset+data.byteLength)}};module.exports=ascii85},{}],7:[function(require,module,exports){const{DataSnapshot:DataSnapshot}=require("./data-snapshot");const{EventStream:EventStream,EventPublisher:EventPublisher}=require("./subscription");const{ID:ID}=require("./id");const debug=require("./debug");const{PathInfo:PathInfo}=require("./path-info");class DataRetrievalOptions{constructor(options){if(!options){options={}}if(typeof options.include!=="undefined"&&!(options.include instanceof Array)){throw new TypeError(`options.include must be an array`)}if(typeof options.exclude!=="undefined"&&!(options.exclude instanceof Array)){throw new TypeError(`options.exclude must be an array`)}if(typeof options.child_objects!=="undefined"&&typeof options.child_objects!=="boolean"){throw new TypeError(`options.child_objects must be a boolean`)}this.include=options.include||undefined;this.exclude=options.exclude||undefined;this.child_objects=typeof options.child_objects==="boolean"?options.child_objects:undefined}}class QueryDataRetrievalOptions extends DataRetrievalOptions{constructor(options){super(options);if(typeof options.snapshots!=="undefined"&&typeof options.snapshots!=="boolean"){throw new TypeError(`options.snapshots must be an array`)}this.snapshots=typeof options.snapshots==="boolean"?options.snapshots:undefined}}const _private=Symbol("private");class DataReference{constructor(db,path,vars){if(!path){path=""}path=path.replace(/^\/|\/$/g,"");const pathInfo=PathInfo.get(path);const key=pathInfo.key;const callbacks=[];this[_private]={get path(){return path},get key(){return key},get callbacks(){return callbacks},vars:vars||{}};this.db=db}get path(){return this[_private].path}get key(){return this[_private].key}get parent(){let currentPath=PathInfo.fillVariables2(this.path,this.vars);const info=PathInfo.get(currentPath);if(info.parentPath===null){return null}return new DataReference(this.db,info.parentPath)}get vars(){return this[_private].vars}child(childPath){childPath=childPath.replace(/^\/|\/$/g,"");const currentPath=PathInfo.fillVariables2(this.path,this.vars);const targetPath=PathInfo.getChildPath(currentPath,childPath);return new DataReference(this.db,targetPath)}set(value,onComplete=undefined){if(this.isWildcardPath){throw new Error(`Cannot set the value of a path with wildcards and/or variables`)}if(this.parent===null){throw new Error(`Cannot set the root object. Use update, or set individual child properties`)}if(typeof value==="undefined"){throw new TypeError(`Cannot store value undefined`)}value=this.db.types.serialize(this.path,value);return this.db.api.set(this.path,value).then(res=>{if(typeof onComplete==="function"){try{onComplete(null,this)}catch(err){console.error(`Error in onComplete callback:`,err)}}}).catch(err=>{if(typeof onComplete==="function"){try{onComplete(err)}catch(err){console.error(`Error in onComplete callback:`,err)}}else{throw err}}).then(()=>{return this})}update(updates,onComplete=undefined){if(this.isWildcardPath){throw new Error(`Cannot update the value of a path with wildcards and/or variables`)}let promise;if(typeof updates!=="object"||updates instanceof Array||updates instanceof ArrayBuffer||updates instanceof Date){promise=this.set(updates)}else{updates=this.db.types.serialize(this.path,updates);promise=this.db.api.update(this.path,updates)}return promise.then(()=>{if(typeof onComplete==="function"){try{onComplete(null,this)}catch(err){console.error(`Error in onComplete callback:`,err)}}}).catch(err=>{if(typeof onComplete==="function"){try{onComplete(err)}catch(err){console.error(`Error in onComplete callback:`,err)}}else{throw err}}).then(()=>{return this})}transaction(callback){if(this.isWildcardPath){throw new Error(`Cannot start a transaction on a path with wildcards and/or variables`)}let cb=currentValue=>{currentValue=this.db.types.deserialize(this.path,currentValue);const snap=new DataSnapshot(this,currentValue);let newValue;try{newValue=callback(snap)}catch(err){return}if(newValue instanceof Promise){return newValue.then(val=>{return this.db.types.serialize(this.path,val)})}else{return this.db.types.serialize(this.path,newValue)}};return this.db.api.transaction(this.path,cb).then(result=>{return this})}on(event,callback,cancelCallbackOrContext,context){if(this.path===""&&["value","notify_value","child_changed","notify_child_changed"].includes(event)){console.warn(`WARNING: Listening for value and child_changed events on the root node is a bad practice`)}const cancelCallback=typeof cancelCallbackOrContext==="function"&&cancelCallbackOrContext;context=typeof cancelCallbackOrContext==="object"?cancelCallbackOrContext:context;const useCallback=typeof callback==="function";let eventPublisher=null;const eventStream=new EventStream(publisher=>{eventPublisher=publisher});let cb={subscr:eventStream,original:callback,ours:(err,path,newValue,oldValue)=>{if(err){debug.error(`Error getting data for event ${event} on path "${path}"`,err);return}let ref=this.db.ref(path);ref[_private].vars=PathInfo.extractVariables(this.path,path);let callbackObject;if(event.startsWith("notify_")){callbackObject=ref}else{const isRemoved=event==="child_removed";const val=this.db.types.deserialize(path,isRemoved?oldValue:newValue);const snap=new DataSnapshot(ref,val,isRemoved);callbackObject=snap}useCallback&&callback.call(context||null,callbackObject);let keep=eventPublisher.publish(callbackObject);if(!keep&&!useCallback){let callbacks=this[_private].callbacks;callbacks.splice(callbacks.indexOf(cb),1);this.db.api.unsubscribe(this.path,event,cb.ours)}}};this[_private].callbacks.push(cb);let authorized=this.db.api.subscribe(this.path,event,cb.ours);const allSubscriptionsStoppedCallback=()=>{let callbacks=this[_private].callbacks;callbacks.splice(callbacks.indexOf(cb),1);this.db.api.unsubscribe(this.path,event,cb.ours)};if(authorized instanceof Promise){authorized.then(()=>{eventPublisher.start(allSubscriptionsStoppedCallback)}).catch(err=>{let callbacks=this[_private].callbacks;callbacks.splice(callbacks.indexOf(cb),1);this.db.api.unsubscribe(this.path,event,cb.ours);eventPublisher.cancel(err.message);cancelCallback&&cancelCallback(err.message)})}else{eventPublisher.start(allSubscriptionsStoppedCallback)}if(callback&&!this.isWildcardPath){if(event==="value"){this.get(snap=>{eventPublisher.publish(snap);useCallback&&callback(snap)})}else if(event==="child_added"){this.get(snap=>{const val=snap.val();if(val===null||typeof val!=="object"){return}Object.keys(val).forEach(key=>{let childSnap=new DataSnapshot(this.child(key),val[key]);eventPublisher.publish(childSnap);useCallback&&callback(childSnap)})})}}return eventStream}off(event=undefined,callback=undefined){const callbacks=this[_private].callbacks;if(callback){const cb=callbacks.find(cb=>cb.original===callback);if(!cb){debug.error(`Can't find specified callback to unsubscribe from (path: "${this.path}", event: ${event}, callback: ${callback})`);return}callbacks.splice(callbacks.indexOf(cb),1);callback=cb.ours;cb.subscr.unsubscribe(callback)}else{callbacks.splice(0,callbacks.length).forEach(cb=>{cb.subscr.unsubscribe()})}this.db.api.unsubscribe(this.path,event,callback);return this}get(optionsOrCallback=undefined,callback=undefined){if(this.isWildcardPath){throw new Error(`Cannot get the value of a path with wildcards and/or variables. Use .query() instead`)}callback=typeof optionsOrCallback==="function"?optionsOrCallback:typeof callback==="function"?callback:undefined;const options=typeof optionsOrCallback==="object"?optionsOrCallback:undefined;const promise=this.db.api.get(this.path,options).then(value=>{value=this.db.types.deserialize(this.path,value);const snapshot=new DataSnapshot(this,value);return snapshot});if(callback){promise.then(callback);return}else{return promise}}once(event,options){if(event==="value"&&!this.isWildcardPath){return this.get(options)}return new Promise((resolve,reject)=>{const callback=snap=>{this.off(event,snap);resolve(snap)};this.on(event,callback)})}push(value=undefined,onComplete=undefined){if(this.isWildcardPath){throw new Error(`Cannot push to a path with wildcards and/or variables`)}const id=ID.generate();const ref=this.child(id);ref.__pushed=true;if(typeof value!=="undefined"){return ref.set(value,onComplete).then(res=>ref)}else{return ref}}remove(){if(this.isWildcardPath){throw new Error(`Cannot remove a path with wildcards and/or variables. Use query().remove instead`)}if(this.parent===null){throw new Error(`Cannot remove the top node`)}return this.set(null)}exists(){if(this.isWildcardPath){throw new Error(`Cannot push to a path with wildcards and/or variables`)}return this.db.api.exists(this.path)}get isWildcardPath(){return this.path.indexOf("*")>=0||this.path.indexOf("$")>=0}query(){return new DataReferenceQuery(this)}reflect(type,args){if(this.pathHasVariables){throw new Error(`Cannot reflect on a path with wildcards and/or variables`)}return this.db.api.reflect(this.path,type,args)}export(stream,options={format:"json"}){return this.db.api.export(this.path,stream,options)}}class DataReferenceQuery{constructor(ref){this.ref=ref;this[_private]={filters:[],skip:0,take:0,order:[]}}filter(key,op,compare){if((op==="in"||op==="!in")&&(!(compare instanceof Array)||compare.length===0)){throw new Error(`${op} filter for ${key} must supply an Array compare argument containing at least 1 value`)}if((op==="between"||op==="!between")&&(!(compare instanceof Array)||compare.length!==2)){throw new Error(`${op} filter for ${key} must supply an Array compare argument containing 2 values`)}if((op==="matches"||op==="!matches")&&!(compare instanceof RegExp)){throw new Error(`${op} filter for ${key} must supply a RegExp compare argument`)}if((op==="contains"||op==="!contains")&&(typeof compare==="object"&&!(compare instanceof Array)&&!(compare instanceof Date)||compare instanceof Array&&compare.length===0)){throw new Error(`${op} filter for ${key} must supply a simple value or (non-zero length) array compare argument`)}this[_private].filters.push({key:key,op:op,compare:compare});return this}where(key,op,compare){return this.filter(key,op,compare)}take(n){this[_private].take=n;return this}skip(n){this[_private].skip=n;return this}sort(key,ascending=true){if(typeof key!=="string"){throw`key must be a string`}this[_private].order.push({key:key,ascending:ascending});return this}order(key,ascending=true){return this.sort(key,ascending)}get(optionsOrCallback=undefined,callback=undefined){callback=typeof optionsOrCallback==="function"?optionsOrCallback:typeof callback==="function"?callback:undefined;const options=typeof optionsOrCallback==="object"?optionsOrCallback:new QueryDataRetrievalOptions({snapshots:true});if(typeof options.snapshots==="undefined"){options.snapshots=true}options.eventHandler=ev=>{if(!this._events||!this._events[ev.name]){return false}const listeners=this._events[ev.name];if(typeof listeners!=="object"||listeners.length===0){return false}if(["add","change","remove"].includes(ev.name)){const ref=new DataReference(this.ref.db,ev.path);const eventData={name:ev.name};if(options.snapshots&&ev.name!=="remove"){const val=db.types.deserialize(ev.path,ev.value);eventData.snapshot=new DataSnapshot(ref,val,false)}else{eventData.ref=ref}ev=eventData}listeners.forEach(callback=>{try{callback(ev)}catch(e){}})};options.monitor={add:false,change:false,remove:false};if(this._events){if(this._events["add"]&&this._events["add"].length>0){options.monitor.add=true}if(this._events["change"]&&this._events["change"].length>0){options.monitor.change=true}if(this._events["remove"]&&this._events["remove"].length>0){options.monitor.remove=true}}const db=this.ref.db;return db.api.query(this.ref.path,this[_private],options).catch(err=>{throw new Error(err)}).then(results=>{results.forEach((result,index)=>{if(options.snapshots){const val=db.types.deserialize(result.path,result.val);results[index]=new DataSnapshot(db.ref(result.path),val)}else{results[index]=db.ref(result)}});if(options.snapshots){return DataSnapshotsArray.from(results)}else{return DataReferencesArray.from(results)}}).then(results=>{callback&&callback(results);return results})}getRefs(callback=undefined){return this.get({snapshots:false},callback)}remove(callback){return this.get({snapshots:false}).then(refs=>{const promises=[];return Promise.all(refs.map(ref=>ref.remove())).then(()=>{callback&&callback()})})}on(event,callback){if(!this._events){this._events={}}if(!this._events[event]){this._events[event]=[]}this._events[event].push(callback);return this}off(event,callback){if(!this._events){return this}if(typeof event==="undefined"){this._events={};return this}if(!this._events[event]){return this}if(typeof callback==="undefined"){delete this._events[event];return this}const index=!this._events[event].indexOf(callback);if(!~index){return this}this._events[event].splice(index,1);return this}}class DataSnapshotsArray extends Array{static from(snaps){const arr=new DataSnapshotsArray(snaps.length);snaps.forEach((snap,i)=>arr[i]=snap);return arr}getValues(){return this.map(snap=>snap.val())}}class DataReferencesArray extends Array{static from(refs){const arr=new DataReferencesArray(refs.length);refs.forEach((ref,i)=>arr[i]=ref);return arr}getPaths(){return this.map(ref=>ref.path)}}module.exports={DataReference:DataReference,DataReferenceQuery:DataReferenceQuery,DataRetrievalOptions:DataRetrievalOptions,QueryDataRetrievalOptions:QueryDataRetrievalOptions}},{"./data-snapshot":8,"./debug":9,"./id":10,"./path-info":12,"./subscription":14}],8:[function(require,module,exports){const{DataReference:DataReference}=require("./data-reference");const{getPathKeys:getPathKeys}=require("./path-info");const getChild=(snapshot,path)=>{if(!snapshot.exists()){return null}let child=snapshot.val();getPathKeys(path).every(key=>{child=child[key];return typeof child!=="undefined"});return child||null};const getChildren=snapshot=>{if(!snapshot.exists()){return[]}let value=snapshot.val();if(value instanceof Array){return new Array(value.length).map((v,i)=>i)}if(typeof value==="object"){return Object.keys(value)}return[]};class DataSnapshot{constructor(ref,value,isRemoved=false){this.ref=ref;this.val=()=>{return value};this.exists=()=>{if(isRemoved){return false}return value!==null&&typeof value!=="undefined"}}child(path){let child=getChild(this,path);return new DataSnapshot(this.ref.child(path),child)}hasChild(path){return getChild(this,path)!==null}hasChildren(){return getChildren(this).length>0}numChildren(){return getChildren(this).length}forEach(callback){const value=this.val();return getChildren(this).every((key,i)=>{const snap=new DataSnapshot(this.ref.child(key),value[key]);return callback(snap)})}get key(){return this.ref.key}}module.exports={DataSnapshot:DataSnapshot}},{"./data-reference":7,"./path-info":12}],9:[function(require,module,exports){class DebugLogger{constructor(level="log",prefix=""){this.prefix=prefix;this.setLevel(level)}setLevel(level){const prefix=this.prefix?this.prefix:"";this.level=level;this.verbose=["verbose"].includes(level)?console.log.bind(console,prefix):()=>{};this.log=["verbose","log"].includes(level)?console.log.bind(console,prefix):()=>{};this.warn=["verbose","log","warn"].includes(level)?console.warn.bind(console,prefix):()=>{};this.error=["verbose","log","warn","error"].includes(level)?console.error.bind(console,prefix):()=>{};this.write=console.log.bind(console)}}module.exports=DebugLogger},{}],10:[function(require,module,exports){const cuid=require("cuid");class ID{static generate(){return cuid().slice(1)}}module.exports={ID:ID}},{cuid:1}],11:[function(require,module,exports){const{AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings}=require("./acebase-base");const{Api:Api}=require("./api");const{DataReference:DataReference,DataReferenceQuery:DataReferenceQuery,DataRetrievalOptions:DataRetrievalOptions,QueryDataRetrievalOptions:QueryDataRetrievalOptions}=require("./data-reference");const{DataSnapshot:DataSnapshot}=require("./data-snapshot");const DebugLogger=require("./debug");const{ID:ID}=require("./id");const{PathReference:PathReference}=require("./path-reference");const{EventStream:EventStream,EventPublisher:EventPublisher,EventSubscription:EventSubscription}=require("./subscription");const Transport=require("./transport");const{TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions}=require("./type-mappings");const Utils=require("./utils");const{PathInfo:PathInfo}=require("./path-info");const ascii85=require("./ascii85");module.exports={AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings,Api:Api,DataReference:DataReference,DataReferenceQuery:DataReferenceQuery,DataRetrievalOptions:DataRetrievalOptions,QueryDataRetrievalOptions:QueryDataRetrievalOptions,DataSnapshot:DataSnapshot,DebugLogger:DebugLogger,ID:ID,PathReference:PathReference,EventStream:EventStream,EventPublisher:EventPublisher,EventSubscription:EventSubscription,Transport:Transport,TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions,Utils:Utils,PathInfo:PathInfo,ascii85:ascii85}},{"./acebase-base":4,"./api":5,"./ascii85":6,"./data-reference":7,"./data-snapshot":8,"./debug":9,"./id":10,"./path-info":12,"./path-reference":13,"./subscription":14,"./transport":15,"./type-mappings":16,"./utils":17}],12:[function(require,module,exports){function getPathKeys(path){if(path.length===0){return[]}let keys=path.replace(/\[/g,"/[").split("/");keys.forEach((key,index)=>{if(key.startsWith("[")){keys[index]=parseInt(key.substr(1,key.length-2))}});return keys}function getPathInfo(path){if(path.length===0){return{parent:null,key:""}}const i=Math.max(path.lastIndexOf("/"),path.lastIndexOf("["));const parentPath=i<0?"":path.substr(0,i);let key=i<0?path:path.substr(i);if(key.startsWith("[")){key=parseInt(key.substr(1,key.length-2))}else if(key.startsWith("/")){key=key.substr(1)}if(parentPath===path){parentPath=null}return{parent:parentPath,key:key}}function getChildPath(path,key){if(path.length===0){if(typeof key==="number"){throw new TypeError("Cannot add array index to root path!")}return key}if(typeof key==="number"){return`${path}[${key}]`}return`${path}/${key}`}class PathInfo{static get(path){return new PathInfo(path)}static getChildPath(path,childKey){return getChildPath(path,childKey)}static getPathKeys(path){return getPathKeys(path)}constructor(path){this.path=path}get key(){return getPathInfo(this.path).key}get parentPath(){return getPathInfo(this.path).parent}childPath(childKey){return getChildPath(`${this.path}`,childKey)}get pathKeys(){return getPathKeys(this.path)}static extractVariables(varPath,fullPath){if(!varPath.includes("*")&&!varPath.includes("$")){return[]}const keys=getPathKeys(varPath);const pathKeys=getPathKeys(fullPath);let count=0;const variables={get length(){return count}};keys.forEach((key,index)=>{const pathKey=pathKeys[index];if(key==="*"){variables[count++]=pathKey}else if(typeof key==="string"&&key[0]==="$"){variables[count++]=pathKey;variables[key]=pathKey;const varName=key.slice(1);if(typeof variables[varName]==="undefined"){variables[varName]=pathKey}}});return variables}static fillVariables(varPath,fullPath){if(varPath.indexOf("*")<0&&varPath.indexOf("$")<0){return varPath}const keys=getPathKeys(varPath);const pathKeys=getPathKeys(fullPath);let merged=keys.map((key,index)=>{if(key===pathKeys[index]||index>=pathKeys.length){return key}else if(typeof key==="string"&&(key==="*"||key[0]==="$")){return pathKeys[index]}else{throw new Error(`Path "${fullPath}" cannot be used to fill variables of path "${this.path}" because they do not match`)}});let mergedPath="";merged.forEach(key=>{if(typeof key==="number"){mergedPath+=`[${key}]`}else{if(mergedPath.length>0){mergedPath+="/"}mergedPath+=key}});return mergedPath}static fillVariables2(varPath,vars){if(typeof vars!=="object"||Object.keys(vars).length===0){return varPath}let pathKeys=getPathKeys(varPath);let n=0;const targetPath=pathKeys.reduce((path,key)=>{if(key==="*"||key.startsWith("$")){key=vars[n++]}if(typeof key==="number"){return`${path}[${key}]`}else{return`${path}/${key}`}},"");return targetPath}equals(otherPath){if(this.path===otherPath){return true}const keys=getPathKeys(this.path);const otherKeys=getPathKeys(otherPath);if(keys.length!==otherKeys.length){return false}return keys.every((key,index)=>{const otherKey=otherKeys[index];return otherKey===key||typeof otherKey==="string"&&(otherKey==="*"||otherKey[0]==="$")||typeof key==="string"&&(key==="*"||key[0]==="$")})}isAncestorOf(descendantPath){if(descendantPath===""||this.path===descendantPath){return false}if(this.path===""){return true}const ancestorKeys=getPathKeys(this.path);const descendantKeys=getPathKeys(descendantPath);if(ancestorKeys.length>=descendantKeys.length){return false}return ancestorKeys.every((key,index)=>{const otherKey=descendantKeys[index];return otherKey===key||typeof otherKey==="string"&&(otherKey==="*"||otherKey[0]==="$")||typeof key==="string"&&(key==="*"||key[0]==="$")})}isDescendantOf(ancestorPath){if(this.path===""||this.path===ancestorPath){return false}if(ancestorPath===""){return true}const ancestorKeys=getPathKeys(ancestorPath);const descendantKeys=getPathKeys(this.path);if(ancestorKeys.length>=descendantKeys.length){return false}return ancestorKeys.every((key,index)=>{const otherKey=descendantKeys[index];return otherKey===key||typeof otherKey==="string"&&(otherKey==="*"||otherKey[0]==="$")||typeof key==="string"&&(key==="*"||key[0]==="$")})}isChildOf(otherPath){if(this.path===""){return false}const parentInfo=PathInfo.get(this.parentPath);return parentInfo.equals(otherPath)}isParentOf(otherPath){if(otherPath===""){return false}const parentInfo=PathInfo.get(PathInfo.get(otherPath).parentPath);return parentInfo.equals(this.path)}}module.exports={getPathInfo:getPathInfo,getChildPath:getChildPath,getPathKeys:getPathKeys,PathInfo:PathInfo}},{}],13:[function(require,module,exports){class PathReference{constructor(path){this.path=path}}module.exports={PathReference:PathReference}},{}],14:[function(require,module,exports){class EventSubscription{constructor(stop){this.stop=stop;this._internal={state:"init",cancelReason:undefined,activatePromises:[]}}activated(callback=undefined){if(callback){this._internal.activatePromises.push({callback:callback});if(this._internal.state==="active"){callback(true)}else if(this._internal.state==="canceled"){callback(false,this._internal.cancelReason)}}return new Promise((resolve,reject)=>{if(this._internal.state==="active"){return resolve()}else if(this._internal.state==="canceled"&&!callback){return reject(new Error(this._internal.cancelReason))}this._internal.activatePromises.push({resolve:resolve,reject:callback?()=>{}:reject})})}_setActivationState(activated,cancelReason){this._internal.cancelReason=cancelReason;this._internal.state=activated?"active":"canceled";while(this._internal.activatePromises.length>0){const p=this._internal.activatePromises.shift();if(activated){p.callback&&p.callback(true);p.resolve&&p.resolve()}else{p.callback&&p.callback(false,cancelReason);p.reject&&p.reject(cancelReason)}}}}class EventPublisher{constructor(publish,start,cancel){this.publish=publish;this.start=start;this.cancel=cancel}}class EventStream{constructor(eventPublisherCallback){const subscribers=[];let noMoreSubscribersCallback;let activationState;const _stoppedState="stopped (no more subscribers)";this.subscribe=(callback,activationCallback)=>{if(typeof callback!=="function"){throw new TypeError("callback must be a function")}else if(activationState===_stoppedState){throw new Error("stream can't be used anymore because all subscribers were stopped")}const sub={callback:callback,activationCallback:function(activated,cancelReason){activationCallback&&activationCallback(activated,cancelReason);this.subscription._setActivationState(activated,cancelReason)},subscription:new EventSubscription((function stop(){subscribers.splice(subscribers.indexOf(this),1);checkActiveSubscribers()}))};subscribers.push(sub);if(typeof activationState!=="undefined"){if(activationState===true){activationCallback&&activationCallback(true);sub.subscription._setActivationState(true)}else if(typeof activationState==="string"){activationCallback&&activationCallback(false,activationState);sub.subscription._setActivationState(false,activationState)}}return sub.subscription};const checkActiveSubscribers=()=>{if(subscribers.length===0){noMoreSubscribersCallback&&noMoreSubscribersCallback();activationState=_stoppedState}};this.unsubscribe=(callback=undefined)=>{const remove=callback?subscribers.filter(sub=>sub.callback===callback):subscribers;remove.forEach(sub=>{const i=subscribers.indexOf(sub);subscribers.splice(i,1)});checkActiveSubscribers()};this.stop=()=>{subscribers.splice(0);checkActiveSubscribers()};const publish=val=>{subscribers.forEach(sub=>{try{sub.callback(val)}catch(err){debug.error(`Error running subscriber callback: ${err.message}`)}});return subscribers.length>0};const start=allSubscriptionsStoppedCallback=>{activationState=true;noMoreSubscribersCallback=allSubscriptionsStoppedCallback;subscribers.forEach(sub=>{sub.activationCallback&&sub.activationCallback(true)})};const cancel=reason=>{activationState=reason;subscribers.forEach(sub=>{sub.activationCallback&&sub.activationCallback(false,reason||new Error("unknown reason"))});subscribers.splice()};const publisher=new EventPublisher(publish,start,cancel);eventPublisherCallback(publisher)}}module.exports={EventStream:EventStream,EventPublisher:EventPublisher,EventSubscription:EventSubscription}},{}],15:[function(require,module,exports){const{PathReference:PathReference}=require("./path-reference");const{cloneObject:cloneObject}=require("./utils");const ascii85=require("./ascii85");module.exports={deserialize(data){if(data.map===null||typeof data.map==="undefined"){return data.val}const deserializeValue=(type,val)=>{if(type==="date"){return new Date(val)}else if(type==="binary"){return ascii85.decode(val)}else if(type==="reference"){return new PathReference(val)}else if(type==="regexp"){return new RegExp(val.pattern,val.flags)}return val};if(typeof data.map==="string"){return deserializeValue(data.map,data.val)}Object.keys(data.map).forEach(path=>{const type=data.map[path];const keys=path.replace(/\[/g,"/[").split("/");keys.forEach((key,index)=>{if(key.startsWith("[")){keys[index]=parseInt(key.substr(1,key.length-2))}});let parent=data;let key="val";let val=data.val;keys.forEach(k=>{key=k;parent=val;val=val[key]});parent[key]=deserializeValue(type,val)});return data.val},serialize(obj){if(obj===null||typeof obj!=="object"||obj instanceof Date||obj instanceof ArrayBuffer||obj instanceof PathReference){const ser=this.serialize({value:obj});return{map:ser.map.value,val:ser.val.value}}obj=cloneObject(obj);const process=(obj,mappings,prefix)=>{Object.keys(obj).forEach(key=>{const val=obj[key];const path=prefix.length===0?key:`${prefix}/${key}`;if(val instanceof Date){obj[key]=val.toISOString();mappings[path]="date"}else if(val instanceof ArrayBuffer){obj[key]=ascii85.encode(val);mappings[path]="binary"}else if(val instanceof PathReference){obj[key]=val.path;mappings[path]="reference"}else if(val instanceof RegExp){obj[key]={pattern:val.source,flags:val.flags};mappings[path]="regexp"}else if(typeof val==="object"&&val!==null){process(val,mappings,path)}})};const mappings={};process(obj,mappings,"");return{map:mappings,val:obj}}}},{"./ascii85":6,"./path-reference":13,"./utils":17}],16:[function(require,module,exports){const{cloneObject:cloneObject}=require("./utils");const{PathInfo:PathInfo}=require("./path-info");const{AceBaseBase:AceBaseBase}=require("./acebase-base");const{DataReference:DataReference}=require("./data-reference");const{DataSnapshot:DataSnapshot}=require("./data-snapshot");const get=(mappings,path)=>{path=path.replace(/^\/|\/$/g,"");const keys=PathInfo.getPathKeys(path);const mappedPath=Object.keys(mappings).find(mpath=>{const mkeys=PathInfo.getPathKeys(mpath);if(mkeys.length!==keys.length){return false}return mkeys.every((mkey,index)=>{if(mkey==="*"||mkey[0]==="$"){return true}return mkey===keys[index]})});const mapping=mappings[mappedPath];return mapping};const map=(mappings,path)=>{const targetPath=PathInfo.get(path).parentPath;if(targetPath===null){return}return get(mappings,targetPath)};const mapDeep=(mappings,entryPath)=>{entryPath=entryPath.replace(/^\/|\/$/g,"");const pathInfo=PathInfo.get(entryPath);const startPath=pathInfo.parentPath;const keys=startPath?PathInfo.getPathKeys(startPath):[];const matches=Object.keys(mappings).reduce((m,mpath)=>{const mkeys=PathInfo.getPathKeys(mpath);if(mkeys.length{if(index>=keys.length){return false}else if(mkey==="*"||mkey[0]==="$"||mkey===keys[index]){return true}else{isMatch=false;return false}})}if(isMatch){const mapping=mappings[mpath];m.push({path:mpath,type:mapping})}return m},[]);return matches};const process=(db,mappings,path,obj,action)=>{if(obj===null||typeof obj!=="object"){return obj}const keys=PathInfo.getPathKeys(path);const m=mapDeep(mappings,path);const changes=[];m.sort((a,b)=>PathInfo.getPathKeys(a.path).length>PathInfo.getPathKeys(b.path).length?-1:1);m.forEach(mapping=>{const mkeys=PathInfo.getPathKeys(mapping.path);mkeys.push("*");const mTrailKeys=mkeys.slice(keys.length);if(mTrailKeys.length===0){const vars=PathInfo.extractVariables(mapping.path,path);const ref=new DataReference(db,path,vars);if(action==="serialize"){obj=mapping.type.serialize(obj,ref)}else if(action==="deserialize"){const snap=new DataSnapshot(ref,obj);obj=mapping.type.deserialize(snap)}return}const process=(parentPath,parent,keys)=>{if(obj===null||typeof obj!=="object"){return obj}const key=keys[0];let children=[];if(key==="*"||key[0]==="$"){if(parent instanceof Array){children=parent.map((val,index)=>({key:index,val:val}))}else{children=Object.keys(parent).map(k=>({key:k,val:parent[k]}))}}else{const child=parent[key];if(typeof child==="object"){children.push({key:key,val:child})}}children.forEach(child=>{const childPath=PathInfo.getChildPath(parentPath,child.key);const vars=PathInfo.extractVariables(mapping.path,childPath);const ref=new DataReference(db,childPath,vars);if(keys.length===1){if(action==="serialize"){changes.push({parent:parent,key:child.key,original:parent[child.key]});parent[child.key]=mapping.type.serialize(child.val,ref)}else if(action==="deserialize"){const snap=new DataSnapshot(ref,child.val);parent[child.key]=mapping.type.deserialize(snap)}}else{process(childPath,child.val,keys.slice(1))}})};process(path,obj,mTrailKeys)});if(action==="serialize"){obj=cloneObject(obj);if(changes.length>0){changes.forEach(change=>{change.parent[change.key]=change.original})}}return obj};class TypeMappingOptions{constructor(options){if(!options){options={}}this.serializer=options.serializer;this.creator=options.creator}}const _mappings=Symbol("mappings");class TypeMappings{constructor(db){this.db=db;this[_mappings]={}}get mappings(){return this[_mappings]}map(path){return map(this[_mappings],path)}bind(path,type,options={}){if(typeof path!=="string"){throw new TypeError("path must be a string")}if(typeof type!=="function"){throw new TypeError("constructor must be a function")}if(typeof options.serializer==="undefined"){}else if(typeof options.serializer==="string"){if(typeof type.prototype[options.serializer]==="function"){options.serializer=type.prototype[options.serializer]}else{throw new TypeError(`${type.name}.prototype.${options.serializer} is not a function, cannot use it as serializer`)}}else if(typeof options.serializer!=="function"){throw new TypeError(`serializer for class ${type.name} must be a function, or the name of a prototype method`)}if(typeof options.creator==="undefined"){if(typeof type.create==="function"){options.creator=type.create}}else if(typeof options.creator==="string"){if(typeof type[options.creator]==="function"){options.creator=type[options.creator]}else{throw new TypeError(`${type.name}.${options.creator} is not a function, cannot use it as creator`)}}else if(typeof options.creator!=="function"){throw new TypeError(`creator for class ${type.name} must be a function, or the name of a static method`)}path=path.replace(/^\/|\/$/g,"");this[_mappings][path]={db:this.db,type:type,creator:options.creator,serializer:options.serializer,deserialize(snap){let obj;if(this.creator){obj=this.creator.call(this.type,snap)}else{obj=new this.type(snap)}return obj},serialize(obj,ref){if(this.serializer){obj=this.serializer.call(obj,ref,obj)}else if(obj&&typeof obj.serialize==="function"){obj=obj.serialize(ref,obj)}return obj}}}serialize(path,obj){return process(this.db,this[_mappings],path,obj,"serialize")}deserialize(path,obj){return process(this.db,this[_mappings],path,obj,"deserialize")}}module.exports={TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions}},{"./acebase-base":4,"./data-reference":7,"./data-snapshot":8,"./path-info":12,"./utils":17}],17:[function(require,module,exports){(function(Buffer){const{PathReference:PathReference}=require("./path-reference");function numberToBytes(number){const bytes=new Uint8Array(8);const view=new DataView(bytes.buffer);view.setFloat64(0,number);return new Array(...bytes)}function bytesToNumber(bytes){if(bytes.length<8){throw new TypeError("must be 8 bytes")}const bin=new Uint8Array(bytes);const view=new DataView(bin.buffer);const nr=view.getFloat64(0);return nr}function encodeString(str){if(typeof TextEncoder!=="undefined"){const encoder=new TextEncoder;return encoder.encode(str)}else if(typeof Buffer==="function"){const buf=Buffer.from(str,"utf-8");return new Uint8Array(buf.buffer,buf.byteOffset,buf.byteLength)}else{let arr=[];for(let i=0;i128){if((code&55296)===55296){const nextCode=str.charCodeAt(i+1);if((nextCode&56320)!==56320){throw new Error("follow-up utf-16 character does not start with 0xDC00")}i++;const p1=code&1023;const p2=nextCode&1023;code=65536|p1<<10|p2}if(code<2048){const b1=192|code>>6&31;const b2=128|code&63;arr.push(b1,b2)}else if(code<65536){const b1=224|code>>12&15;const b2=128|code>>6&63;const b3=128|code&63;arr.push(b1,b2,b3)}else if(code<2097152){const b1=240|code>>18&7;const b2=128|code>>12&63;const b3=128|code>>6&63;const b4=128|code&63;arr.push(b1,b2,b3,b4)}else{throw new Error(`Cannot convert character ${str.charAt(i)} (code ${code}) to utf-8`)}}else{arr.push(code<128?code:63)}}return new Uint8Array(arr)}}function decodeString(buffer){if(typeof TextDecoder!=="undefined"){const decoder=new TextDecoder;if(buffer instanceof Uint8Array){return decoder.decode(buffer)}const buf=Uint8Array.from(buffer);return decoder.decode(buf)}else if(typeof Buffer==="function"){if(buffer instanceof Buffer){return buffer.toString("utf-8")}else if(buffer instanceof Array){const typedArray=Uint8Array.from(buffer);const buf=Buffer.from(typedArray.buffer,typedArray.byteOffset,typedArray.byteOffset+typedArray.byteLength);return buf.toString("utf-8")}else if("buffer"in buffer&&buffer["buffer"]instanceof ArrayBuffer){const buf=Buffer.from(buffer["buffer"],buffer.byteOffset,buffer.byteOffset+buffer.byteLength);return buf.toString("utf-8")}else{throw new Error(`Unsupported buffer argument`)}}else{if(!(buffer instanceof Uint8Array)&&"buffer"in buffer&&buffer["buffer"]instanceof ArrayBuffer){buffer=new Uint8Array(buffer["buffer"],buffer.byteOffset,buffer.byteLength)}if(buffer instanceof Buffer||buffer instanceof Array||buffer instanceof Uint8Array){let str="";for(let i=0;i128){if((code&240)===240){const b1=code,b2=buffer[i+1],b3=buffer[i+2],b4=buffer[i+3];code=(b1&7)<<18|(b2&63)<<12|(b3&63)<<6|b4&63;i+=3}else if((code&224)===224){const b1=code,b2=buffer[i+1],b3=buffer[i+2];code=(b1&15)<<12|(b2&63)<<6|b3&63;i+=2}else if((code&192)===192){const b1=code,b2=buffer[i+1];code=(b1&31)<<6|b2&63;i++}else{throw new Error(`invalid utf-8 data`)}}if(code>=65536){code^=65536;const p1=55296|code>>10;const p2=56320|code&1023;str+=String.fromCharCode(p1);str+=String.fromCharCode(p2)}else{str+=String.fromCharCode(code)}}return str}else{throw new Error(`Unsupported buffer argument`)}}}function concatTypedArrays(a,b){const c=new a.constructor(a.length+b.length);c.set(a);c.set(b,a.length);return c}function cloneObject(original,stack){const{DataSnapshot:DataSnapshot}=require("./data-snapshot");if(original instanceof DataSnapshot){throw new TypeError(`Object to clone is a DataSnapshot (path "${original.ref.path}")`)}const checkAndFixTypedArray=obj=>{if(obj!==null&&typeof obj==="object"&&typeof obj.constructor==="function"&&typeof obj.constructor.name==="string"&&["Buffer","Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","BigUint64Array","BigInt64Array"].includes(obj.constructor.name)){obj=obj.buffer.slice(obj.byteOffset,obj.byteOffset+obj.byteLength)}return obj};original=checkAndFixTypedArray(original);if(typeof original!=="object"||original===null||original instanceof Date||original instanceof ArrayBuffer||original instanceof PathReference||original instanceof RegExp){return original}const cloneValue=val=>{if(stack.indexOf(val)>=0){throw new ReferenceError(`object contains a circular reference`)}val=checkAndFixTypedArray(val);if(val===null||val instanceof Date||val instanceof ArrayBuffer||val instanceof PathReference||val instanceof RegExp){return val}else if(val instanceof Array){stack.push(val);val=val.map(item=>cloneValue(item));stack.pop();return val}else if(typeof val==="object"){stack.push(val);val=cloneObject(val,stack);stack.pop();return val}else{return val}};if(typeof stack==="undefined"){stack=[original]}const clone={};Object.keys(original).forEach(key=>{let val=original[key];if(typeof val==="function"){return}clone[key]=cloneValue(val)});return clone}function compareValues(oldVal,newVal){const voids=[undefined,null];if(oldVal===newVal){return"identical"}else if(voids.indexOf(oldVal)>=0&&voids.indexOf(newVal)<0){return"added"}else if(voids.indexOf(oldVal)<0&&voids.indexOf(newVal)>=0){return"removed"}else if(typeof oldVal!==typeof newVal){return"changed"}else if(typeof oldVal==="object"){const isArray=oldVal instanceof Array;const oldKeys=isArray?Object.keys(oldVal).map(v=>parseInt(v)):Object.keys(oldVal);const newKeys=isArray?Object.keys(newVal).map(v=>parseInt(v)):Object.keys(newVal);const removedKeys=oldKeys.filter(key=>newKeys.indexOf(key)<0);const addedKeys=newKeys.filter(key=>oldKeys.indexOf(key)<0);const changedKeys=newKeys.reduce((changed,key)=>{if(oldKeys.indexOf(key)>=0){const val1=oldVal[key];const val2=newVal[key];const c=compareValues(val1,val2);if(c!=="identical"){changed.push({key:key,change:c})}}return changed},[]);if(addedKeys.length===0&&removedKeys.length===0&&changedKeys.length===0){return"identical"}else{return{added:addedKeys,removed:removedKeys,changed:changedKeys}}}else if(oldVal!==newVal){return"changed"}return"identical"}const getChildValues=(childKey,oldValue,newValue)=>{oldValue=oldValue===null?null:oldValue[childKey];if(typeof oldValue==="undefined"){oldValue=null}newValue=newValue===null?null:newValue[childKey];if(typeof newValue==="undefined"){newValue=null}return{oldValue:oldValue,newValue:newValue}};module.exports={numberToBytes:numberToBytes,bytesToNumber:bytesToNumber,concatTypedArrays:concatTypedArrays,cloneObject:cloneObject,compareValues:compareValues,getChildValues:getChildValues,encodeString:encodeString,decodeString:decodeString}}).call(this,require("buffer").Buffer)},{"./data-snapshot":8,"./path-reference":13,buffer:39}],18:[function(require,module,exports){var colors={};module["exports"]=colors;colors.themes={};var util=require("util");var ansiStyles=colors.styles=require("./styles");var defineProps=Object.defineProperties;var newLineRegex=new RegExp(/[\r\n]+/g);colors.supportsColor=require("./system/supports-colors").supportsColor;if(typeof colors.enabled==="undefined"){colors.enabled=colors.supportsColor()!==false}colors.enable=function(){colors.enabled=true};colors.disable=function(){colors.enabled=false};colors.stripColors=colors.strip=function(str){return(""+str).replace(/\x1B\[\d+m/g,"")};var stylize=colors.stylize=function stylize(str,style){if(!colors.enabled){return str+""}return ansiStyles[style].open+str+ansiStyles[style].close};var matchOperatorsRe=/[|\\{}()[\]^$+*?.]/g;var escapeStringRegexp=function(str){if(typeof str!=="string"){throw new TypeError("Expected a string")}return str.replace(matchOperatorsRe,"\\$&")};function build(_styles){var builder=function builder(){return applyStyle.apply(builder,arguments)};builder._styles=_styles;builder.__proto__=proto;return builder}var styles=function(){var ret={};ansiStyles.grey=ansiStyles.gray;Object.keys(ansiStyles).forEach((function(key){ansiStyles[key].closeRe=new RegExp(escapeStringRegexp(ansiStyles[key].close),"g");ret[key]={get:function(){return build(this._styles.concat(key))}}}));return ret}();var proto=defineProps((function colors(){}),styles);function applyStyle(){var args=Array.prototype.slice.call(arguments);var str=args.map((function(arg){if(arg!=undefined&&arg.constructor===String){return arg}else{return util.inspect(arg)}})).join(" ");if(!colors.enabled||!str){return str}var newLinesPresent=str.indexOf("\n")!=-1;var nestedStyles=this._styles;var i=nestedStyles.length;while(i--){var code=ansiStyles[nestedStyles[i]];str=code.open+str.replace(code.closeRe,code.open)+code.close;if(newLinesPresent){str=str.replace(newLineRegex,(function(match){return code.close+match+code.open}))}}return str}colors.setTheme=function(theme){if(typeof theme==="string"){console.log("colors.setTheme now only accepts an object, not a string. "+"If you are trying to set a theme from a file, it is now your (the "+"caller's) responsibility to require the file. The old syntax "+"looked like colors.setTheme(__dirname + "+"'/../themes/generic-logging.js'); The new syntax looks like "+"colors.setTheme(require(__dirname + "+"'/../themes/generic-logging.js'));");return}for(var style in theme){(function(style){colors[style]=function(str){if(typeof theme[style]==="object"){var out=str;for(var i in theme[style]){out=colors[theme[style][i]](out)}return out}return colors[theme[style]](str)}})(style)}};function init(){var ret={};Object.keys(styles).forEach((function(name){ret[name]={get:function(){return build([name])}}}));return ret}var sequencer=function sequencer(map,str){var exploded=str.split("");exploded=exploded.map(map);return exploded.join("")};colors.trap=require("./custom/trap");colors.zalgo=require("./custom/zalgo");colors.maps={};colors.maps.america=require("./maps/america")(colors);colors.maps.zebra=require("./maps/zebra")(colors);colors.maps.rainbow=require("./maps/rainbow")(colors);colors.maps.random=require("./maps/random")(colors);for(var map in colors.maps){(function(map){colors[map]=function(str){return sequencer(colors.maps[map],str)}})(map)}defineProps(colors,init())},{"./custom/trap":19,"./custom/zalgo":20,"./maps/america":23,"./maps/rainbow":24,"./maps/random":25,"./maps/zebra":26,"./styles":27,"./system/supports-colors":29,util:45}],19:[function(require,module,exports){module["exports"]=function runTheTrap(text,options){var result="";text=text||"Run the trap, drop the bass";text=text.split("");var trap={a:["@","Ą","Ⱥ","Ʌ","Δ","Λ","Д"],b:["ß","Ɓ","Ƀ","ɮ","β","฿"],c:["©","Ȼ","Ͼ"],d:["Ð","Ɗ","Ԁ","ԁ","Ԃ","ԃ"],e:["Ë","ĕ","Ǝ","ɘ","Σ","ξ","Ҽ","੬"],f:["Ӻ"],g:["ɢ"],h:["Ħ","ƕ","Ң","Һ","Ӈ","Ԋ"],i:["༏"],j:["Ĵ"],k:["ĸ","Ҡ","Ӄ","Ԟ"],l:["Ĺ"],m:["ʍ","Ӎ","ӎ","Ԡ","ԡ","൩"],n:["Ñ","ŋ","Ɲ","Ͷ","Π","Ҋ"],o:["Ø","õ","ø","Ǿ","ʘ","Ѻ","ם","۝","๏"],p:["Ƿ","Ҏ"],q:["্"],r:["®","Ʀ","Ȑ","Ɍ","ʀ","Я"],s:["§","Ϟ","ϟ","Ϩ"],t:["Ł","Ŧ","ͳ"],u:["Ʊ","Ս"],v:["ט"],w:["Ш","Ѡ","Ѽ","൰"],x:["Ҳ","Ӿ","Ӽ","ӽ"],y:["¥","Ұ","Ӌ"],z:["Ƶ","ɀ"]};text.forEach((function(c){c=c.toLowerCase();var chars=trap[c]||[" "];var rand=Math.floor(Math.random()*chars.length);if(typeof trap[c]!=="undefined"){result+=trap[c][rand]}else{result+=c}}));return result}},{}],20:[function(require,module,exports){module["exports"]=function zalgo(text,options){text=text||" he is here ";var soul={up:["̍","̎","̄","̅","̿","̑","̆","̐","͒","͗","͑","̇","̈","̊","͂","̓","̈","͊","͋","͌","̃","̂","̌","͐","̀","́","̋","̏","̒","̓","̔","̽","̉","ͣ","ͤ","ͥ","ͦ","ͧ","ͨ","ͩ","ͪ","ͫ","ͬ","ͭ","ͮ","ͯ","̾","͛","͆","̚"],down:["̖","̗","̘","̙","̜","̝","̞","̟","̠","̤","̥","̦","̩","̪","̫","̬","̭","̮","̯","̰","̱","̲","̳","̹","̺","̻","̼","ͅ","͇","͈","͉","͍","͎","͓","͔","͕","͖","͙","͚","̣"],mid:["̕","̛","̀","́","͘","̡","̢","̧","̨","̴","̵","̶","͜","͝","͞","͟","͠","͢","̸","̷","͡"," ҉"]};var all=[].concat(soul.up,soul.down,soul.mid);function randomNumber(range){var r=Math.floor(Math.random()*range);return r}function isChar(character){var bool=false;all.filter((function(i){bool=i===character}));return bool}function heComes(text,options){var result="";var counts;var l;options=options||{};options["up"]=typeof options["up"]!=="undefined"?options["up"]:true;options["mid"]=typeof options["mid"]!=="undefined"?options["mid"]:true;options["down"]=typeof options["down"]!=="undefined"?options["down"]:true;options["size"]=typeof options["size"]!=="undefined"?options["size"]:"maxi";text=text.split("");for(l in text){if(isChar(l)){continue}result=result+text[l];counts={up:0,down:0,mid:0};switch(options.size){case"mini":counts.up=randomNumber(8);counts.mid=randomNumber(2);counts.down=randomNumber(8);break;case"maxi":counts.up=randomNumber(16)+3;counts.mid=randomNumber(4)+1;counts.down=randomNumber(64)+3;break;default:counts.up=randomNumber(8)+1;counts.mid=randomNumber(6)/2;counts.down=randomNumber(8)+1;break}var arr=["up","mid","down"];for(var d in arr){var index=arr[d];for(var i=0;i<=counts[index];i++){if(options[index]){result=result+soul[index][randomNumber(soul[index].length)]}}}}return result}return heComes(text,options)}},{}],21:[function(require,module,exports){var colors=require("./colors");module["exports"]=function(){var addProperty=function(color,func){String.prototype.__defineGetter__(color,func)};addProperty("strip",(function(){return colors.strip(this)}));addProperty("stripColors",(function(){return colors.strip(this)}));addProperty("trap",(function(){return colors.trap(this)}));addProperty("zalgo",(function(){return colors.zalgo(this)}));addProperty("zebra",(function(){return colors.zebra(this)}));addProperty("rainbow",(function(){return colors.rainbow(this)}));addProperty("random",(function(){return colors.random(this)}));addProperty("america",(function(){return colors.america(this)}));var x=Object.keys(colors.styles);x.forEach((function(style){addProperty(style,(function(){return colors.stylize(this,style)}))}));function applyTheme(theme){var stringPrototypeBlacklist=["__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__","charAt","constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf","charCodeAt","indexOf","lastIndexOf","length","localeCompare","match","repeat","replace","search","slice","split","substring","toLocaleLowerCase","toLocaleUpperCase","toLowerCase","toUpperCase","trim","trimLeft","trimRight"];Object.keys(theme).forEach((function(prop){if(stringPrototypeBlacklist.indexOf(prop)!==-1){console.log("warn: ".red+("String.prototype"+prop).magenta+" is probably something you don't want to override. "+"Ignoring style name")}else{if(typeof theme[prop]==="string"){colors[prop]=colors[theme[prop]]}else{var tmp=colors[theme[prop][0]];for(var t=1;t=2,has16m:level>=3}}function supportsColor(stream){if(forceColor===false){return 0}if(hasFlag("color=16m")||hasFlag("color=full")||hasFlag("color=truecolor")){return 3}if(hasFlag("color=256")){return 2}if(stream&&!stream.isTTY&&forceColor!==true){return 0}var min=forceColor?1:0;if(process.platform==="win32"){var osRelease=os.release().split(".");if(Number(process.versions.node.split(".")[0])>=8&&Number(osRelease[0])>=10&&Number(osRelease[2])>=10586){return Number(osRelease[2])>=14931?3:2}return 1}if("CI"in env){if(["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some((function(sign){return sign in env}))||env.CI_NAME==="codeship"){return 1}return min}if("TEAMCITY_VERSION"in env){return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION)?1:0}if("TERM_PROGRAM"in env){var version=parseInt((env.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(env.TERM_PROGRAM){case"iTerm.app":return version>=3?3:2;case"Hyper":return 3;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(env.TERM)){return 2}if(/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)){return 1}if("COLORTERM"in env){return 1}if(env.TERM==="dumb"){return min}return min}function getSupportLevel(stream){var level=supportsColor(stream);return translateLevel(level)}module.exports={supportsColor:getSupportLevel,stdout:getSupportLevel(process.stdout),stderr:getSupportLevel(process.stderr)}}).call(this,require("_process"))},{"./has-flag.js":28,_process:43,os:42}],30:[function(require,module,exports){const{AceBaseBase:AceBaseBase,AceBaseSettings:AceBaseSettings}=require("acebase-core");const{StorageSettings:StorageSettings}=require("./storage");const{LocalApi:LocalApi}=require("./api-local");class AceBaseLocalSettings{constructor(options){if(!options){options={}}this.logLevel=options.logLevel||"log";this.storage=options.storage}}class AceBase extends AceBaseBase{constructor(dbname,options){options=new AceBaseLocalSettings(options);super(dbname,options);const apiSettings={db:this,storage:options.storage,logLevel:options.logLevel};this.api=new LocalApi(dbname,apiSettings,ready=>{this.emit("ready")})}}module.exports={AceBase:AceBase,AceBaseLocalSettings:AceBaseLocalSettings}},{"./api-local":31,"./storage":38,"acebase-core":11}],31:[function(require,module,exports){const{Api:Api,Utils:Utils}=require("acebase-core");const{AceBase:AceBase}=require("./acebase-local");const{StorageSettings:StorageSettings}=require("./storage");const{AceBaseStorage:AceBaseStorage,AceBaseStorageSettings:AceBaseStorageSettings}=require("./storage-acebase");const{SQLiteStorage:SQLiteStorage,SQLiteStorageSettings:SQLiteStorageSettings}=require("./storage-sqlite");const{MSSQLStorage:MSSQLStorage,MSSQLStorageSettings:MSSQLStorageSettings}=require("./storage-mssql");const{LocalStorage:LocalStorage,LocalStorageSettings:LocalStorageSettings}=require("./storage-localstorage");const{Node:Node}=require("./node");const{DataIndex:DataIndex}=require("./data-index");class LocalApi extends Api{constructor(dbname="default",settings,readyCallback){super();this.db=settings.db;if(typeof settings.storage==="object"){settings.storage.logLevel=settings.logLevel;if(SQLiteStorageSettings&&(settings.storage instanceof SQLiteStorageSettings||settings.storage.type==="sqlite")){this.storage=new SQLiteStorage(dbname,settings.storage)}else if(MSSQLStorageSettings&&(settings.storage instanceof MSSQLStorageSettings||settings.storage.type==="mssql")){this.storage=new MSSQLStorage(dbname,settings.storage)}else if(LocalStorageSettings&&(settings.storage instanceof LocalStorageSettings||settings.storage.type==="localstorage")){this.storage=new LocalStorage(dbname,settings.storage)}else{const storageSettings=settings.storage instanceof AceBaseStorageSettings?settings.storage:new AceBaseStorageSettings(settings.storage);this.storage=new AceBaseStorage(dbname,storageSettings)}}else{settings.storage=new AceBaseStorageSettings({logLevel:settings.logLevel});this.storage=new AceBaseStorage(dbname,settings.storage)}this.storage.on("ready",readyCallback)}stats(options){return Promise.resolve(this.storage.stats)}subscribe(path,event,callback){this.storage.subscriptions.add(path,event,callback)}unsubscribe(path,event=undefined,callback=undefined){this.storage.subscriptions.remove(path,event,callback)}set(path,value,flags=undefined){return Node.update(this.storage,path,value,{merge:false})}update(path,updates,flags=undefined){return Node.update(this.storage,path,updates,{merge:true})}get(path,options){return Node.getValue(this.storage,path,options)}transaction(path,callback){return Node.transaction(this.storage,path,callback)}exists(path){return Node.exists(this.storage,path)}query2(path,query,options={snapshots:false,include:undefined,exclude:undefined,child_objects:undefined}){}query(path,query,options={snapshots:false,include:undefined,exclude:undefined,child_objects:undefined,eventHandler:event=>{}}){if(typeof options!=="object"){options={}}if(typeof options.snapshots==="undefined"){options.snapshots=false}const sortMatches=matches=>{matches.sort((a,b)=>{const compare=i=>{const o=query.order[i];let left=a.val[o.key];let right=b.val[o.key];if(typeof left==="undefined"&&typeof right!=="undefined"){return o.ascending?-1:1}if(typeof left!=="undefined"&&typeof right==="undefined"){return o.ascending?1:-1}if(typeof left==="undefined"&&typeof right==="undefined"){return 0}if(left==right){if(iright){return o.ascending?1:-1}};return compare(0)})};const loadResultsData=(preResults,options)=>{if(preResults.length===0){return Promise.resolve([])}const maxBatchSize=50;let batches=[];const items=preResults.map((result,index)=>({path:result.path,index:index}));while(items.length>0){let batchItems=items.splice(0,maxBatchSize);batches.push(batchItems)}const results=[];const nextBatch=()=>{const batch=batches.shift();return Promise.all(batch.map(item=>{const{path:path,index:index}=item;return Node.getValue(this.storage,path,options).then(val=>{if(val===null){this.storage.debug.warn(`Indexed result "/${path}" does not have a record!`);return}const result={path:path,val:val};if(stepsExecuted.sorted){results[index]=result}else{results.push(result);if(!stepsExecuted.skipped&&results.length>query.skip+query.take){sortMatches(results);results.pop()}}})})).then(()=>{if(batches.length>0){return nextBatch()}})};return nextBatch().then(()=>{return results})};const isWildcardPath=path.indexOf("*")>=0||path.indexOf("$")>=0;const availableIndexes=this.storage.indexes.get(path);const usingIndexes=[];query.filters.forEach(filter=>{if(filter.index){return}const indexesOnKey=availableIndexes.filter(index=>index.key===filter.key).filter(index=>{return index.validOperators.includes(filter.op)});if(indexesOnKey.length>=1){const otherFilterKeys=query.filters.filter(f=>f!==filter).map(f=>f.key);const sortKeys=query.order.map(o=>o.key).filter(key=>key!==filter.key);const beneficialIndexes=indexesOnKey.map(index=>{const availableKeys=index.includeKeys.concat(index.key);const forOtherFilters=availableKeys.filter(key=>otherFilterKeys.indexOf(key)>=0);const forSorting=availableKeys.filter(key=>sortKeys.indexOf(key)>=0);const forBoth=forOtherFilters.concat(forSorting.filter(index=>forOtherFilters.indexOf(index)<0));const points={filters:forOtherFilters.length,sorting:forSorting.length*(query.take>0?forSorting.length:1),both:forBoth.length*forBoth.length,get total(){return this.filters+this.sorting+this.both}};return{index:index,points:points.total,filterKeys:forOtherFilters,sortKeys:forSorting}});beneficialIndexes.sort((a,b)=>a.points>b.points?-1:1);const bestBenificialIndex=beneficialIndexes[0];filter.index=bestBenificialIndex.index;bestBenificialIndex.filterKeys.forEach(key=>{query.filters.filter(f=>f!==filter&&f.key===key).forEach(f=>{if(!DataIndex.validOperators.includes(f.op)){return}f.indexUsage="filter";f.index=bestBenificialIndex.index})});bestBenificialIndex.sortKeys.forEach(key=>{query.order.filter(s=>s.key===key).forEach(s=>{s.index=bestBenificialIndex.index})})}if(filter.index){usingIndexes.push({index:filter.index,description:filter.index.description})}});if(query.order.length>0&&query.take>0){query.order.forEach(sort=>{if(sort.index){return}sort.index=availableIndexes.filter(index=>index.key===sort.key).find(index=>index.type==="normal")})}const indexDescriptions=usingIndexes.map(index=>index.description).join(", ");usingIndexes.length>0&&this.storage.debug.log(`Using indexes for query: ${indexDescriptions}`);const tableScanFilters=query.filters.filter(filter=>!filter.index);const specialOpsRegex=/^[a-z]+\:/i;if(tableScanFilters.some(filter=>specialOpsRegex.test(filter.op))){const f=tableScanFilters.find(filter=>specialOpsRegex.test(filter.op));const err=new Error(`query contains operator "${f.op}" which requires a special index that was not found on path "${path}", key "${f.key}"`);return Promise.reject(err)}const allowedTableScanOperators=["<","<=","==","!=",">=",">","like","!like","in","!in","matches","!matches","between","!between","has","!has","contains","!contains"];for(let i=0;i0){const keys=tableScanFilters.reduce((keys,f)=>{if(keys.indexOf(f.key)<0){keys.push(f.key)}return keys},[]).map(key=>`"${key}"`);const err=new Error(`This wildcard path query on "/${path}" requires index(es) on key(s): ${keys.join(", ")}. Create the index(es) and retry`);return Promise.reject(err)}const indexScanPromises=[];query.filters.forEach(filter=>{if(filter.index&&filter.indexUsage!=="filter"){let promise=filter.index.query(filter.op,filter.compare).then(results=>{options.eventHandler&&options.eventHandler({name:"stats",type:"index_query",source:filter.index.description,stats:results.stats});if(results.hints.length>0){options.eventHandler&&options.eventHandler({name:"hints",type:"index_query",source:filter.index.description,hints:results.hints})}return results});const resultFilters=query.filters.filter(f=>f.index===filter.index&&f.indexUsage==="filter");if(resultFilters.length>0){promise=promise.then(results=>{resultFilters.forEach(filter=>{results=results.filterMetadata(filter.key,filter.op,filter.compare)});return results})}indexScanPromises.push(promise)}});const stepsExecuted={filtered:query.filters.length===0,skipped:query.skip===0,taken:query.take===0,sorted:query.order.length===0,preDataLoaded:false,dataLoaded:false};if(query.filters.length===0&&query.take===0){this.storage.debug.error(`Filterless queries must use .take to limit the results. Defaulting to 100 for query on path "${path}"`);query.take=100}if(query.filters.length===0&&query.order.length>0&&query.order[0].index){const sortIndex=query.order[0].index;this.storage.debug.log(`Using index for sorting: ${sortIndex.description}`);const promise=sortIndex.take(query.skip,query.take,query.order[0].ascending).then(results=>{options.eventHandler&&options.eventHandler({name:"stats",type:"sort_index_take",source:filter.index.description,stats:results.stats});if(results.hints.length>0){options.eventHandler&&options.eventHandler({name:"hints",type:"sort_index_take",source:filter.index.description,hints:results.hints})}return results});indexScanPromises.push(promise);stepsExecuted.skipped=true;stepsExecuted.taken=true;stepsExecuted.sorted=true}return Promise.all(indexScanPromises).then(indexResultSets=>{let indexedResults=[];if(indexResultSets.length===1){const resultSet=indexResultSets[0];indexedResults=resultSet.map(match=>{const result={key:match.key,path:match.path,val:{[resultSet.filterKey]:match.value}};match.metadata&&Object.assign(result.val,match.metadata);return result});stepsExecuted.filtered=true}else if(indexResultSets.length>1){indexResultSets.sort((a,b)=>a.length{const result={key:match.key,path:match.path,val:{[shortestSet.filterKey]:match.value}};const matchedInAllSets=otherSets.every(set=>set.findIndex(m=>match.path===match.path)>=0);if(matchedInAllSets){match.metadata&&Object.assign(result.val,match.metadata);otherSets.forEach(set=>{const otherResult=set.find(r=>r.path===result.path);result.val[set.filterKey]=otherResult.value;otherResult.metadata&&Object.assign(result.val,otherResult.metadata)});results.push(result)}return results},[]);stepsExecuted.filtered=true}if(isWildcardPath||indexScanPromises.length>0&&tableScanFilters.length===0){if(query.order.length===0||query.order.every(o=>o.index)){stepsExecuted.preDataLoaded=true;if(!stepsExecuted.sorted&&query.order.length>0){sortMatches(indexedResults)}stepsExecuted.sorted=true;if(!stepsExecuted.skipped&&query.skip>0){indexedResults=indexedResults.slice(query.skip)}if(!stepsExecuted.taken&&query.take>0){indexedResults=indexedResults.slice(0,query.take)}stepsExecuted.skipped=true;stepsExecuted.taken=true;if(!options.snapshots){return indexedResults}const childOptions={include:options.include,exclude:options.exclude,child_objects:options.child_objects};return loadResultsData(indexedResults,childOptions).then(results=>{stepsExecuted.dataLoaded=true;return results})}if(options.snapshots||!stepsExecuted.sorted){const loadPartialResults=query.order.length>0;const childOptions=loadPartialResults?{include:query.order.map(order=>order.key)}:{include:options.include,exclude:options.exclude,child_objects:options.child_objects};return loadResultsData(indexedResults,childOptions).then(results=>{if(query.order.length>0){sortMatches(results)}stepsExecuted.sorted=true;if(query.skip>0){results=results.slice(query.skip)}if(query.take>0){results=results.slice(0,query.take)}stepsExecuted.skipped=true;stepsExecuted.taken=true;if(options.snapshots&&loadPartialResults){return loadResultsData(results,{include:options.include,exclude:options.exclude,child_objects:options.child_objects})}return results})}else{return indexedResults}}let indexKeyFilter;if(indexedResults.length>0){indexKeyFilter=indexedResults.map(result=>result.key)}const promises=[];let matches=[];let preliminaryStop=false;const loadPartialData=query.order.length>0;const childOptions=loadPartialData?{include:query.order.map(order=>order.key)}:{include:options.include,exclude:options.exclude,child_objects:options.child_objects};return Node.getChildren(this.storage,path,indexKeyFilter).next(child=>{if(child.type===Node.VALUE_TYPES.OBJECT){if(!child.address){return}if(preliminaryStop){return false}const p=Node.matches(this.storage,child.address.path,tableScanFilters).then(isMatch=>{if(!isMatch){return null}const childPath=child.address.path;if(options.snapshots||query.order.length>0){return Node.getValue(this.storage,childPath,childOptions).then(val=>{return{path:childPath,val:val}})}else{return{path:childPath}}}).then(result=>{if(result!==null){matches.push(result);if(query.take>0&&matches.length>query.take+query.skip){if(query.order.length>0){sortMatches(matches)}else{preliminaryStop=true}matches.pop()}}});promises.push(p)}}).catch(reason=>{this.storage.debug.warn(`Error getting child stream: ${reason}`);return[]}).then(()=>{return Promise.all(promises).then(()=>{stepsExecuted.preDataLoaded=loadPartialData;stepsExecuted.dataLoaded=!loadPartialData;if(query.order.length>0){sortMatches(matches)}stepsExecuted.sorted=true;if(query.skip>0){matches=matches.slice(query.skip)}stepsExecuted.skipped=true;if(query.take>0){matches=matches.slice(0,query.take)}stepsExecuted.taken=true;if(!stepsExecuted.dataLoaded){return loadResultsData(matches,{include:options.include,exclude:options.exclude,child_objects:options.child_objects}).then(results=>{stepsExecuted.dataLoaded=true;return results})}return matches})})}).then(matches=>{if(!stepsExecuted.sorted&&query.order.length>0){sortMatches(matches)}if(!options.snapshots){matches=matches.map(match=>match.path)}if(!stepsExecuted.skipped&&query.skip>0){matches=matches.slice(query.skip)}if(!stepsExecuted.taken&&query.take>0){matches=matches.slice(0,query.take)}if(options.monitor===true){options.monitor={add:true,change:true,remove:true}}if(typeof options.monitor==="object"&&(options.monitor.add||options.monitor.change||options.monitor.remove)){const matchedPaths=options.snapshots?matches.map(match=>match.path):matches.slice();const ref=this.db.ref(path);const removeMatch=path=>{const index=matchedPaths.indexOf(path);if(index<0){return}matchedPaths.splice(index,1)};const addMatch=path=>{if(matchedPaths.includes(path)){return}matchedPaths.push(path)};const stopMonitoring=()=>{this.unsubscribe(ref.path,"notify_child_changed",childChangedCallback);this.unsubscribe(ref.path,"notify_child_added",childAddedCallback);this.unsubscribe(ref.path,"notify_child_removed",childRemovedCallback)};const childChangedCallback=(err,path,newValue,oldValue)=>{const wasMatch=matchedPaths.includes(path);let keepMonitoring=true;const checkKeys=[];query.filters.forEach(f=>!checkKeys.includes(f.key)&&checkKeys.push(f.key));const seenKeys=[];typeof oldValue==="object"&&Object.keys(oldValue).forEach(key=>!seenKeys.includes(key)&&seenKeys.push(key));typeof newValue==="object"&&Object.keys(newValue).forEach(key=>!seenKeys.includes(key)&&seenKeys.push(key));const missingKeys=[];let isMatch=seenKeys.every(key=>{if(!checkKeys.includes(key)){return true}const filters=query.filters.filter(filter=>filter.key===key);return filters.every(filter=>{if(allowedTableScanOperators.includes(filter.op)){return this.storage.test(newValue[key],filter.op,filter.compare)}if(filter.index.constructor.name==="FullTextDataIndex"&&filter.index.localeKey&&!seenKeys.includes(filter.index.localeKey)){missingKeys.push(filter.index.localeKey);return true}return filter.index.test(newValue,filter.op,filter.compare)})});if(isMatch){missingKeys.push(...checkKeys.filter(key=>!seenKeys.includes(key)));let promise=Promise.resolve(true);if(!wasMatch&&missingKeys.length>0){const filterQueue=query.filters.filter(f=>missingKeys.includes(f.key));const simpleFilters=filterQueue.filter(f=>allowedTableScanOperators.includes(f.op));const indexFilters=filterQueue.filter(f=>!allowedTableScanOperators.includes(f.op));const processFilters=()=>{const checkIndexFilters=()=>{const keysToLoad=indexFilters.reduce((keys,filter)=>{if(!keys.includes(filter.key)){keys.push(filter.key)}if(filter.index.constructor.name==="FullTextDataIndex"&&filter.index.localeKey&&!keys.includes(filter.index.localeKey)){keys.push(filter.index.localeKey)}return keys},[]);return Node.getValue(this.storage,path,{include:keysToLoad}).then(val=>{if(val===null){return false}return indexFilters.every(filter=>filter.index.test(val,filter.op,filter.compare))})};if(simpleFilters.length>0){return Node.matches(this.storage,path,simpleFilters).then(isMatch=>{if(isMatch){if(indexFilters.length===0){return true}return checkIndexFilters()}return false})}else{return checkIndexFilters()}};promise=processFilters()}return promise.then(isMatch=>{if(isMatch){if(!wasMatch){addMatch(path)}let gotValue=value=>{if(wasMatch&&options.monitor.change){keepMonitoring=options.eventHandler({name:"change",path:path,value:value})}else if(!wasMatch&&options.monitor.add){keepMonitoring=options.eventHandler({name:"add",path:path,value:value})}if(keepMonitoring===false){stopMonitoring()}};if(options.snapshots){const loadOptions={include:options.include,exclude:options.exclude,child_objects:options.child_objects};return this.storage.getNodeValue(path,loadOptions).then(gotValue)}else{return gotValue(newValue)}}else if(wasMatch){removeMatch(path);if(options.monitor.remove){keepMonitoring=options.eventHandler({name:"remove",path:path,value:oldValue})}}if(keepMonitoring===false){stopMonitoring()}})}else{if(wasMatch){removeMatch(path);if(options.monitor.remove){keepMonitoring=options.eventHandler({name:"remove",path:path,value:oldValue});if(keepMonitoring===false){stopMonitoring()}}}}};const childAddedCallback=(err,path,newValue,oldValue)=>{let isMatch=query.filters.every(filter=>{if(allowedTableScanOperators.includes(filter.op)){return this.storage.test(newValue[filter.key],filter.op,filter.compare)}else{return filter.index.test(newValue,filter.op,filter.compare)}});let keepMonitoring=true;if(isMatch){addMatch(path);if(options.monitor.add){keepMonitoring=options.eventHandler({name:"add",path:path,value:options.snapshots?newValue:null})}}if(keepMonitoring===false){stopMonitoring()}};const childRemovedCallback=(err,path,newValue,oldValue)=>{let keepMonitoring=true;removeMatch(path);if(options.monitor.remove){keepMonitoring=options.eventHandler({name:"remove",path:path,value:options.snapshots?oldValue:null})}if(keepMonitoring===false){stopMonitoring()}};if(options.monitor.add||options.monitor.change||options.monitor.remove){this.subscribe(ref.path,"notify_child_changed",childChangedCallback)}if(options.monitor.remove){this.subscribe(ref.path,"notify_child_removed",childRemovedCallback)}if(options.monitor.add){this.subscribe(ref.path,"notify_child_added",childAddedCallback)}}return matches})}createIndex(path,key,options){return this.storage.indexes.create(path,key,options)}getIndexes(){return Promise.resolve(this.storage.indexes.list())}reflect(path,type,args){const getChildren=(path,limit=50,skip=0)=>{if(typeof limit==="string"){limit=parseInt(limit)}if(typeof skip==="string"){skip=parseInt(skip)}const children=[];let n=0,stop=skip+limit;return Node.getChildren(this.storage,path).next(childInfo=>{n++;if(limit===0||n<=stop&&n>skip){children.push({key:typeof childInfo.key==="string"?childInfo.key:childInfo.index,type:childInfo.valueTypeName,value:childInfo.value,address:typeof childInfo.address==="object"&&"pageNr"in childInfo.address?{pageNr:childInfo.address.pageNr,recordNr:childInfo.address.recordNr}:undefined})}if(limit>0&&n>stop){return false}}).then(()=>{return{more:limit!==0&&n>stop,list:children}})};switch(type){case"children":{return getChildren(path,args.limit,args.skip)}case"info":{const info={key:"",exists:false,type:"unknown",value:undefined,children:{more:false,list:[]}};return Node.getInfo(this.storage,path).then(nodeInfo=>{info.key=nodeInfo.key;info.exists=nodeInfo.exists;info.type=nodeInfo.valueTypeName;info.value=nodeInfo.value;let hasChildren=nodeInfo.exists&&nodeInfo.address&&[Node.VALUE_TYPES.OBJECT,Node.VALUE_TYPES.ARRAY].includes(nodeInfo.type);if(hasChildren){return getChildren(path,args.child_limit,args.child_skip)}}).then(children=>{info.children=children;return info})}}}export(path,stream,options={format:"json"}){return this.storage.exportNode(path,stream,options)}}module.exports={LocalApi:LocalApi}},{"./acebase-local":30,"./data-index":39,"./node":36,"./storage":38,"./storage-acebase":39,"./storage-localstorage":37,"./storage-mssql":39,"./storage-sqlite":39,"acebase-core":11}],32:[function(require,module,exports){const{DataReference:DataReference,DataSnapshot:DataSnapshot,EventSubscription:EventSubscription,PathReference:PathReference,TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions}=require("acebase-core");const{AceBase:AceBase,AceBaseLocalSettings:AceBaseLocalSettings}=require("./acebase-local");const{LocalStorageSettings:LocalStorageSettings}=require("./storage-localstorage");const acebase={AceBase:AceBase,AceBaseLocalSettings:AceBaseLocalSettings,DataReference:DataReference,DataSnapshot:DataSnapshot,EventSubscription:EventSubscription,PathReference:PathReference,TypeMappings:TypeMappings,TypeMappingOptions:TypeMappingOptions,LocalStorageSettings:LocalStorageSettings};class BrowserAceBase extends acebase.AceBase{constructor(name,settings){settings=settings||{};settings.storage=new acebase.LocalStorageSettings;if(settings.temp===true){settings.storage.session=true;delete settings.temp}super(name,settings)}}window.AceBase=BrowserAceBase;window.acebase=acebase},{"./acebase-local":30,"./storage-localstorage":37,"acebase-core":11}],33:[function(require,module,exports){const{VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}=require("./node-value-types");const{PathInfo:PathInfo}=require("acebase-core");class NodeInfo{constructor(info){this.path=info.path;this.type=info.type;this.index=info.index;this.key=info.key;this.exists=info.exists;this.address=info.address;this.value=info.value;if(typeof this.path==="string"&&(typeof this.key==="undefined"&&typeof this.index==="undefined")){let pathInfo=PathInfo.get(this.path);if(typeof pathInfo.key==="number"){this.index=pathInfo.key}else{this.key=pathInfo.key}}if(typeof this.exists==="undefined"){this.exists=true}}get valueType(){return this.type}get valueTypeName(){return getValueTypeName(this.valueType)}toString(){if(!this.exists){return`"${this.path}" doesn't exist`}if(this.address){return`"${this.path}" is ${this.valueTypeName} stored at ${this.address.pageNr},${this.address.recordNr}`}else{return`"${this.path}" is ${this.valueTypeName} with value ${this.value}`}}}module.exports={NodeInfo:NodeInfo}},{"./node-value-types":35,"acebase-core":11}],34:[function(require,module,exports){const{PathInfo:PathInfo}=require("acebase-core");const SECOND=1e3;const MINUTE=6e4;const DEBUG_MODE=false;const LOCK_TIMEOUT=DEBUG_MODE?15*MINUTE:90*SECOND;const LOCK_STATE={PENDING:"pending",LOCKED:"locked",EXPIRED:"expired",DONE:"done"};class NodeLocker{constructor(){this._locks=[]}_allowLock(path,tid,forWriting){const pathInfo=PathInfo.get(path);const existing=this._locks.find(otherLock=>otherLock.tid===tid&&otherLock.state===LOCK_STATE.LOCKED&&(otherLock.path===path||pathInfo.isDescendantOf(otherLock.path))&&(otherLock.forWriting||!forWriting));if(typeof existing==="object"){return{allow:true}}const conflict=this._locks.filter(otherLock=>otherLock.tid!==tid&&otherLock.state===LOCK_STATE.LOCKED).find(otherLock=>{return(forWriting||otherLock.forWriting)&&(path===otherLock.path||pathInfo.isDescendantOf(otherLock.path))});const clashes=typeof conflict!=="undefined";return{allow:!clashes,conflict:conflict}}_processLockQueue(){const pending=this._locks.filter(lock=>lock.state===LOCK_STATE.PENDING&&(lock.waitingFor===null||lock.waitingFor.state!==LOCK_STATE.LOCKED)).sort((a,b)=>{if(a.priority&&!b.priority){return-1}else if(!a.priority&&b.priority){return 1}return a.requested{const check=this._allowLock(lock.path,lock.tid,lock.forWriting);lock.waitingFor=check.conflict||null;if(check.allow){this.lock(lock).then(lock.resolve).catch(lock.reject)}})}lock(path,tid,forWriting=true,comment="",options={withPriority:false,noTimeout:false}){let lock,proceed;if(path instanceof NodeLock){lock=path;lock.comment=`(retry: ${lock.comment})`;proceed=true}else if(this._locks.findIndex(l=>l.tid===tid&&l.state===LOCK_STATE.EXPIRED)>=0){return Promise.reject(new Error(`lock on tid ${tid} has expired, not allowed to continue`))}else{lock=new NodeLock(this,path,tid,forWriting,options.withPriority===true);lock.comment=comment;this._locks.push(lock);const check=this._allowLock(path,tid,forWriting);lock.waitingFor=check.conflict||null;proceed=check.allow}if(proceed){lock.state=LOCK_STATE.LOCKED;if(typeof lock.granted==="number"){}else{lock.granted=Date.now();if(options.noTimeout!==true){lock.expires=Date.now()+LOCK_TIMEOUT;lock.timeout=setTimeout(()=>{if(lock.state!==LOCK_STATE.LOCKED){return}console.error(`lock :: ${lock.forWriting?"write":"read"} lock on path "/${lock.path}" by tid ${lock.tid} took too long, ${lock.comment}`);lock.state=LOCK_STATE.EXPIRED;this._processLockQueue()},LOCK_TIMEOUT)}}return Promise.resolve(lock)}else{console.assert(lock.state===LOCK_STATE.PENDING);const p=new Promise((resolve,reject)=>{lock.resolve=resolve;lock.reject=reject});return p}}unlock(lockOrId,comment,processQueue=true){let lock,i;if(lockOrId instanceof NodeLock){lock=lockOrId;i=this._locks.indexOf(lock)}else{let id=lockOrId;i=this._locks.findIndex(l=>l.id===id);lock=this._locks[i]}if(i<0){const msg=`lock on "/${lock.path}" for tid ${lock.tid} wasn't found; ${comment}`;return Promise.reject(new Error(msg))}lock.state=LOCK_STATE.DONE;clearTimeout(lock.timeout);this._locks.splice(i,1);processQueue&&this._processLockQueue();return Promise.resolve(lock)}list(){return this._locks||[]}isAllowed(path,tid,forWriting){return this._allowLock(path,tid,forWriting).allow}}let lastid=0;class NodeLock{static get LOCK_STATE(){return LOCK_STATE}constructor(locker,path,tid,forWriting,priority=false){this.locker=locker;this.path=path;this.tid=tid;this.forWriting=forWriting;this.priority=priority;this.state=LOCK_STATE.PENDING;this.requested=Date.now();this.granted=undefined;this.expires=undefined;this.comment="";this.waitingFor=null;this.id=++lastid}release(comment){return this.locker.unlock(this,comment||this.comment)}moveToParent(){const parentPath=PathInfo.get(this.path).parentPath;const allowed=this.locker.isAllowed(parentPath,this.tid,this.forWriting);if(allowed){this.waitingFor=null;this.path=parentPath;this.comment=`moved to parent: ${this.comment}`;return Promise.resolve(this)}else{this.locker.unlock(this,`moveLockToParent: ${this.comment}`,false);return this.locker.lock(parentPath,this.tid,this.forWriting,`moved to parent (queued): ${this.comment}`,{withPriority:true}).then(newLock=>{return newLock})}}moveTo(otherPath,forWriting){const allowed=this.locker.isAllowed(otherPath,this.tid,forWriting);if(allowed){this.waitingFor=null;this.path=otherPath;this.forWriting=forWriting;this.comment=`moved to "/${otherPath}": ${this.comment}`;return Promise.resolve(this)}else{this.locker.unlock(this,`moving to "/${otherPath}": ${this.comment}`,false);return this.locker.lock(otherPath,this.tid,forWriting,`moved to "/${otherPath}" (queued): ${this.comment}`,{withPriority:true}).then(newLock=>{return newLock})}}}module.exports={NodeLocker:NodeLocker,NodeLock:NodeLock}},{"acebase-core":11}],35:[function(require,module,exports){const VALUE_TYPES={OBJECT:1,ARRAY:2,NUMBER:3,BOOLEAN:4,STRING:5,DATETIME:6,BINARY:8,REFERENCE:9};function getValueTypeName(valueType){switch(valueType){case VALUE_TYPES.ARRAY:return"array";case VALUE_TYPES.BINARY:return"binary";case VALUE_TYPES.BOOLEAN:return"boolean";case VALUE_TYPES.DATETIME:return"date";case VALUE_TYPES.NUMBER:return"number";case VALUE_TYPES.OBJECT:return"object";case VALUE_TYPES.REFERENCE:return"reference";case VALUE_TYPES.STRING:return"string";default:"unknown"}}module.exports={VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}},{}],36:[function(require,module,exports){const{Storage:Storage}=require("./storage");const{NodeInfo:NodeInfo}=require("./node-info");const{VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}=require("./node-value-types");const colors=require("colors");class Node{static get VALUE_TYPES(){return VALUE_TYPES}static getInfo(storage,path,options={no_cache:false}){if(options&&!options.no_cache){let cachedInfo=storage.nodeCache.find(path);if(cachedInfo){return Promise.resolve(cachedInfo)}}return storage.getNodeInfo(path).then(info=>{if(options&&!options.no_cache){storage.nodeCache.update(info)}return info})}static update(storage,path,value,options={merge:true}){if(options.merge){return storage.updateNode(path,value)}else{return storage.setNode(path,value)}}static exists(storage,path){return storage.getNodeInfo(path).then(nodeInfo=>{return nodeInfo.exists})}static getValue(storage,path,options={include:undefined,exclude:undefined,child_objects:true}){if(!options){options={}}if(typeof options.include!=="undefined"&&!(options.include instanceof Array)){throw new TypeError(`options.include must be an array of key names`)}if(typeof options.exclude!=="undefined"&&!(options.exclude instanceof Array)){throw new TypeError(`options.exclude must be an array of key names`)}if(["undefined","boolean"].indexOf(typeof options.child_objects)<0){throw new TypeError(`options.child_objects must be a boolean`)}return storage.getNodeValue(path,options)}static getChildInfo(storage,path,childKeyOrIndex){let childInfo;return storage.getChildren(path,{keyFilter:[childKeyOrIndex]}).next(info=>{childInfo=info}).then(()=>{return childInfo})}static getChildren(storage,path,keyFilter=undefined){return storage.getChildren(path,{keyFilter:keyFilter})}static remove(storage,path){return storage.removeNode(path)}static set(storage,path,value){return Node.update(storage,path,value,{merge:false})}static transaction(storage,path,callback){return storage.transactNode(path,callback)}static matches(storage,path,criteria,options){return storage.matchNode(path,criteria,options)}}class NodeChange{static get CHANGE_TYPE(){return{UPDATE:"update",DELETE:"delete",INSERT:"insert"}}constructor(keyOrIndex,changeType,oldValue,newValue){this.keyOrIndex=keyOrIndex;this.changeType=changeType;this.oldValue=oldValue;this.newValue=newValue}}class NodeChangeTracker{constructor(path){this.path=path;this._changes=[];this._oldValue=undefined;this._newValue=undefined}addDelete(keyOrIndex,oldValue){this._changes.push(new NodeChange(keyOrIndex,NodeChange.CHANGE_TYPE.DELETE,oldValue,null))}addUpdate(keyOrIndex,oldValue,newValue){this._changes.push(new NodeChange(keyOrIndex,NodeChange.CHANGE_TYPE.UPDATE,oldValue,newValue))}addInsert(keyOrIndex,newValue){this._changes.push(new NodeChange(keyOrIndex,NodeChange.CHANGE_TYPE.INSERT,null,newValue))}add(keyOrIndex,currentValue,newValue){if(currentValue===null){if(newValue===null){throw new Error(`Wrong logic for node change on "${this.nodeInfo.path}/${keyOrIndex}" - both old and new values are null`)}this.addInsert(keyOrIndex,newValue)}else if(newValue===null){this.addDelete(keyOrIndex,currentValue)}else{this.addUpdate(keyOrIndex,currentValue,newValue)}}get updates(){return this._changes.filter(change=>change.changeType===NodeChange.CHANGE_TYPE.UPDATE)}get deletes(){return this._changes.filter(change=>change.changeType===NodeChange.CHANGE_TYPE.DELETE)}get inserts(){return this._changes.filter(change=>change.changeType===NodeChange.CHANGE_TYPE.INSERT)}get all(){return this._changes}get totalChanges(){return this._changes.length}get(keyOrIndex){return this._changes.find(change=>change.keyOrIndex===keyOrIndex)}hasChanged(keyOrIndex){return!!this.get(keyOrIndex)}get newValue(){if(typeof this._newValue==="object"){return this._newValue}if(typeof this._oldValue==="undefined"){throw new TypeError(`oldValue is not set`)}let newValue={};Object.keys(this.oldValue).forEach(key=>newValue[key]=oldValue[key]);this.deletes.forEach(change=>delete newValue[change.key]);this.updates.forEach(change=>newValue[change.key]=change.newValue);this.inserts.forEach(change=>newValue[change.key]=change.newValue);return newValue}set newValue(value){this._newValue=value}get oldValue(){if(typeof this._oldValue==="object"){return this._oldValue}if(typeof this._newValue==="undefined"){throw new TypeError(`newValue is not set`)}let oldValue={};Object.keys(this.newValue).forEach(key=>oldValue[key]=newValue[key]);this.deletes.forEach(change=>oldValue[change.key]=change.oldValue);this.updates.forEach(change=>oldValue[change.key]=change.oldValue);this.inserts.forEach(change=>delete oldValue[change.key]);return oldValue}set oldValue(value){this._oldValue=value}get typeChanged(){return typeof this.oldValue!==typeof this.newValue||this.oldValue instanceof Array&&!(this.newValue instanceof Array)||this.newValue instanceof Array&&!(this.oldValue instanceof Array)}static create(path,oldValue,newValue){const changes=new NodeChangeTracker(path);changes.oldValue=oldValue;changes.newValue=newValue;typeof oldValue==="object"&&Object.keys(oldValue).forEach(key=>{if(typeof newValue==="object"&&key in newValue&&newValue!==null){changes.add(key,oldValue[key],newValue[key])}else{changes.add(key,oldValue[key],null)}});typeof newValue==="object"&&Object.keys(newValue).forEach(key=>{if(typeof oldValue!=="object"||!(key in oldValue)||oldValue[key]===null){changes.add(key,null,newValue[key])}});return changes}}module.exports={Node:Node,NodeInfo:NodeInfo}},{"./node-info":33,"./node-value-types":35,"./storage":38,colors:22}],37:[function(require,module,exports){const{debug:debug,ID:ID,PathReference:PathReference,PathInfo:PathInfo,ascii85:ascii85}=require("acebase-core");const{NodeInfo:NodeInfo}=require("./node-info");const{VALUE_TYPES:VALUE_TYPES}=require("./node-value-types");const{Storage:Storage,StorageSettings:StorageSettings,NodeNotFoundError:NodeNotFoundError}=require("./storage");class LocalStorageSettings extends StorageSettings{constructor(settings){super(settings);settings=settings||{};this.session=settings.session===true;this.provider=typeof settings.provider==="object"?settings.provider:null}}class LocalStorageNodeAddress{constructor(containerPath){this.path=containerPath}}class LocalStorageNodeInfo extends NodeInfo{constructor(info){super(info);this.address;this.revision=info.revision;this.revision_nr=info.revision_nr;this.created=info.created;this.modified=info.modified}}class LocalStorage extends Storage{constructor(dbname,settings){super(dbname,settings);this._init()}_init(){if(this.settings.provider!==null&&typeof this.settings.provider==="object"){this._localStorage=this.settings.provider}else{if(!this.settings.session&&typeof localStorage==="undefined"){throw new Error(`No localStorage available. If you are on Node: npm i node-localstorage`)}if(this.settings.session===true&&typeof sessionStorage==="undefined"){throw new Error(`No sessionStorage available`)}this._localStorage=this.settings.session===true?sessionStorage:localStorage}this.debug.log(`Database "${this.name}" details:`.intro);this.debug.log(`- Type: LocalStorage`);this.debug.log(`- Max inline value size: ${this.settings.maxInlineValueSize}`.intro);return this.getNodeInfo("").then(info=>{if(!info.exists){return this._writeNode("",{})}}).then(()=>{return this.indexes.supported&&this.indexes.load()}).then(()=>{this.emit("ready")})}get _keyPrefix(){return`${this.name}.acebase::`}_getPathFromKey(key){return key.slice(this._keyPrefix.length)}_getKeyFromPath(path){return`${this._keyPrefix}${path}`}_storeNode(path,info){const getTypedChildValue=val=>{if(val===null){throw new Error(`Not allowed to store null values. remove the property`)}else if(["string","number","boolean"].includes(typeof val)){return val}else if(val instanceof Date){return{type:VALUE_TYPES.DATETIME,value:val.getTime()}}else if(val instanceof PathReference){return{type:VALUE_TYPES.REFERENCE,value:child.path}}else if(val instanceof ArrayBuffer){return{type:VALUE_TYPES.BINARY,value:ascii85.encode(val)}}else if(typeof val==="object"){console.assert(Object.keys(val).length===0,"child object stored in parent can only be empty");return val}};const unprocessed=`Caller should have pre-processed the value by converting it to a string`;if(info.type===VALUE_TYPES.ARRAY&&info.value instanceof Array){console.warn(`Unprocessed array. ${unprocessed}`);const obj={};for(let i=0;i{info.value[key]=getTypedChildValue(original[key])})}const json=JSON.stringify(info);this._localStorage.setItem(this._getKeyFromPath(path),json)}_readNode(path){let val=this._localStorage.getItem(this._getKeyFromPath(path));if(val===null){return null}val=JSON.parse(val);const getTypedChildValue=val=>{if(val.type===VALUE_TYPES.BINARY){return ascii85.decode(val.value)}else if(val.type===VALUE_TYPES.DATETIME){return new Date(val.value)}else if(val.type===VALUE_TYPES.REFERENCE){return new PathReference(val.value)}else{throw new Error(`Unhandled child value type ${val.type}`)}};const node={type:val.type,value:val.value,revision:val.revision,revision_nr:val.revision_nr,created:val.created,modified:val.modified};switch(val.type){case VALUE_TYPES.ARRAY:case VALUE_TYPES.OBJECT:{const obj=val.value;Object.keys(obj).forEach(key=>{let item=obj[key];if(typeof item==="object"&&"type"in item){obj[key]=getTypedChildValue(item)}});node.value=obj;break}case VALUE_TYPES.BINARY:{node.value=ascii85.decode(val.value);break}case VALUE_TYPES.STRING:{node.value=val.value;break}case VALUE_TYPES.REFERENCE:{node.value=new PathReference(val.value);break}default:throw new Error(`Invalid standalone record value type`)}return node}_getTypeFromStoredValue(val){let type;if(typeof val==="string"){type=VALUE_TYPES.STRING}else if(typeof val==="number"){type=VALUE_TYPES.NUMBER}else if(typeof val==="boolean"){type=VALUE_TYPES.BOOLEAN}else if(val instanceof Array){type=VALUE_TYPES.ARRAY}else if(typeof val==="object"){if("type"in val){type=val.type;val=val.value;if(type===VALUE_TYPES.DATETIME){val=new Date(val)}else if(type===VALUE_TYPES.REFERENCE){val=new PathReference(val)}}else{type=VALUE_TYPES.OBJECT}}else{throw new Error(`Unknown value type`)}return{type:type,value:val}}_writeNode(path,value,options={merge:false,revision:null}){if(this.valueFitsInline(value)&&path!==""){throw new Error(`invalid value to store in its own node`)}else if(path===""&&(typeof value!=="object"||value instanceof Array)){throw new Error(`Invalid root node value. Must be an object`)}const currentRow=this._readNode(path);const newRevision=options&&options.revision||ID.generate();let mainNode={type:VALUE_TYPES.OBJECT,value:{}};const childNodeValues={};if(value instanceof Array){mainNode.type=VALUE_TYPES.ARRAY;const obj={};for(let i=0;i{const val=value[key];delete mainNode.value[key];if(val===null){return}if(this.valueFitsInline(val)){mainNode.value[key]=val}else{childNodeValues[key]=val}})}if(currentRow){this.debug.log(`Node "/${path}" is being ${options.merge?"updated":"overwritten"}`.cyan);if(currentIsObjectOrArray||newIsObjectOrArray){const pathInfo=PathInfo.get(path);const keys=[];for(let i=0;i{if(!children.new.includes(key)){children.new.push(key)}})}const changes={insert:children.new.filter(key=>!children.current.includes(key)),update:children.new.filter(key=>children.current.includes(key)),delete:options&&options.merge?Object.keys(value).filter(key=>value[key]===null):children.current.filter(key=>!children.new.includes(key))};Object.keys(childNodeValues).map(key=>{const childPath=PathInfo.getChildPath(path,key);const childValue=childNodeValues[key];this._writeNode(childPath,childValue,{revision:newRevision,merge:false})});const movingNodes=keys.filter(key=>key in mainNode.value);const deleteDedicatedKeys=changes.delete.concat(movingNodes);deleteDedicatedKeys.forEach(key=>{const childPath=PathInfo.getChildPath(path,key);this._deleteNode(childPath)})}this._storeNode(path,{type:mainNode.type,value:mainNode.value,revision:currentRow.revision,revision_nr:currentRow.revision_nr+1,created:currentRow.created,modified:Date.now()})}else{this.debug.log(`Node "/${path}" is being created`.cyan);Object.keys(childNodeValues).map(key=>{const childPath=PathInfo.getChildPath(path,key);const childValue=childNodeValues[key];this._writeNode(childPath,childValue,{revision:newRevision,merge:false})});this._storeNode(path,{type:mainNode.type,value:mainNode.value,revision:newRevision,revision_nr:1,created:Date.now(),modified:Date.now()})}}_deleteNode(path){this._localStorage.removeItem(this._getKeyFromPath(path));for(let i=0;i{let lock,canceled=false;const tid=options&&options.tid||ID.generate();return this.nodeLocker.lock(path,tid,false,"getChildren").then(l=>{lock=l;let row=this._localStorage.getItem(this._getKeyFromPath(path));if(!row){throw new NodeNotFoundError(`Node "/${path}" does not exist`)}row=JSON.parse(row);if(![VALUE_TYPES.OBJECT,VALUE_TYPES.ARRAY].includes(row.type)){return}const isArray=row.type===VALUE_TYPES.ARRAY;const value=row.value;let keys=Object.keys(value);if(options.keyFilter){keys=keys.filter(key=>options.keyFilter.includes(key))}const pathInfo=PathInfo.get(path);keys.length>0&&keys.every(key=>{let child=this._getTypeFromStoredValue(value[key]);const info=new LocalStorageNodeInfo({path:pathInfo.childPath(key),key:isArray?null:key,index:isArray?key:null,type:child.type,address:null,exists:true,value:child.value,revision:row.revision,revision_nr:row.revision_nr,created:row.created,modified:row.modified});canceled=callback(info)===false;return!canceled});if(canceled){return}const childRows=[];for(let i=0;i{const row=childRows[i];if(!row){return}const key=PathInfo.get(row.path).key;if(options.keyFilter&&!options.keyFilter.includes(key)){return handleNextChild(i+1)}const info=new LocalStorageNodeInfo({path:row.path,type:row.type,key:isArray?null:key,index:isArray?key:null,address:new LocalStorageNodeAddress(row.path),exists:true,value:null,revision:row.revision,revision_nr:row.revision_nr,created:new Date(row.created),modified:new Date(row.modified)});canceled=callback(info)===false;if(!canceled){return handleNextChild(i+1)}};return handleNextChild(0)}).then(()=>{lock.release();return canceled}).catch(err=>{lock.release();throw err})};return generator}getNode(path,options={include:undefined,exclude:undefined,child_objects:true,tid:undefined}){const tid=options&&options.tid||ID.generate();let lock;return this.nodeLocker.lock(path,tid,false,"getNode").then(l=>{lock=l;const filtered=options&&(options.include||options.exclude||options.child_objects===false);const pathInfo=PathInfo.get(path);const targetRow=this._readNode(path);if(!targetRow){if(path===""){return{value:null}}return lock.moveToParent().then(parentLock=>{lock=parentLock;let parentNode=this._readNode(pathInfo.parentPath);if(parentNode&&[VALUE_TYPES.OBJECT,VALUE_TYPES.ARRAY].includes(parentNode.type)&&pathInfo.key in parentNode){return{revision:parentNode.revision,value:parentNode.value[pathInfo.key]}}return{value:null}})}const includeCheck=options.include?new RegExp("^"+options.include.map(p=>"(?:"+p.replace(/\*/g,"[^/\\[]+")+")").join("|")+"(?:$|[/\\[])"):null;const excludeCheck=options.exclude?new RegExp("^"+options.exclude.map(p=>"(?:"+p.replace(/\*/g,"[^/\\[]+")+")").join("|")+"(?:$|[/\\[])"):null;const childRows=[];for(let i=0;ipathInfo.pathKeys.length+1)){include=false}if(include){childRow.path=otherPath;childRows.push(childRow)}}this.debug.log(`Read node "/${path}" and ${filtered?"(filtered) ":""}children from ${childRows.length+1} records`.magenta);const result={revision:targetRow?targetRow.revision:null,value:targetRow.value};const objectToArray=obj=>{const arr=[];Object.keys(obj).forEach(key=>{let index=parseInt(key);arr[index]=obj[index]});return arr};if(targetRow.type===VALUE_TYPES.ARRAY){result.value=objectToArray(result.value)}if(targetRow.type===VALUE_TYPES.OBJECT||targetRow.type===VALUE_TYPES.ARRAY){const targetPathKeys=PathInfo.getPathKeys(path);let value=targetRow.value;for(let i=0;i{console.assert(!(childKey in parent[key]),"child key is in parent value already?! HOW?!");parent[key][childKey]=nodeValue[childKey]})}else{parent[key]=nodeValue}parent=parent[key]}}}else if(childRows.length>0){throw new Error(`multiple records found for non-object value!`)}if(options.child_objects===false){Object.keys(result.value).forEach(key=>{if(typeof result.value[key]==="object"&&result.value[key].constructor===Object){console.assert(Object.keys(result.value[key]).length===0);delete result.value[key]}})}if(options.exclude){const process=(obj,keys)=>{if(typeof obj!=="object"){return}const key=keys[0];if(key==="*"){Object.keys(obj).forEach(k=>{process(obj[k],keys.slice(1))})}else if(keys.length>1){key in obj&&process(obj[key],keys.slice(1))}else{delete obj[key]}};options.exclude.forEach(path=>{const checkKeys=PathInfo.getPathKeys(path);process(result.value,checkKeys)})}return result}).then(result=>{lock.release();return result}).catch(err=>{lock.release();throw err})}getNodeInfo(path,options={tid:undefined}){const pathInfo=PathInfo.get(path);const tid=options&&options.tid||ID.generate();let lock;return this.nodeLocker.lock(path,tid,false,"getNodeInfo").then(l=>{lock=l;const node=this._readNode(path);const info=new LocalStorageNodeInfo({path:path,key:typeof pathInfo.key==="string"?pathInfo.key:null,index:typeof pathInfo.key==="number"?pathInfo.key:null,type:node?node.type:0,exists:node!==null,address:node?new LocalStorageNodeAddress(path):null,created:node?new Date(node.created):null,modified:node?new Date(node.modified):null,revision:node?node.revision:null,revision_nr:node?node.revision_nr:null});if(node||path===""){return info}return lock.moveToParent().then(parentLock=>{lock=parentLock;const parent=this._readNode(pathInfo.parentPath);if(parent&&[VALUE_TYPES.OBJECT,VALUE_TYPES.ARRAY].includes(parent.type)&&pathInfo.key in parent.value){info.exists=true;info.value=parent.value[pathInfo.key];info.address=null;info.type=parent.type;info.created=new Date(parent.created);info.modified=new Date(parent.modified);info.revision=parent.revision;info.revision_nr=parent.revision_nr}else{info.address=null}return info})}).then(info=>{lock.release();return info}).catch(err=>{lock&&lock.release();throw err})}removeNode(path,options={tid:undefined}){if(path===""){return Promise.reject(new Error(`Cannot remove the root node`))}const pathInfo=PathInfo.get(path);const tid=options&&options.tid||ID.generate();return this.nodeLocker.lock(pathInfo.parentPath,tid,true,"removeNode").then(lock=>{return this.updateNode(pathInfo.parentPath,{[pathInfo.key]:null},{tid:tid}).then(result=>{lock.release();return result}).catch(err=>{lock.release();throw err})})}setNode(path,value,options={assert_revision:undefined,tid:undefined}){const pathInfo=PathInfo.get(path);let lock;const tid=options&&options.tid||ID.generate();return this.nodeLocker.lock(path,tid,true,"setNode").then(l=>{lock=l;if(path===""){if(value===null||typeof value!=="object"||value instanceof Array||value instanceof ArrayBuffer||"buffer"in value&&value.buffer instanceof ArrayBuffer){return Promise.reject(new Error(`Invalid value for root node: ${value}`))}return this._writeNodeWithTracking("",value,{merge:false,tid:tid})}if(options&&typeof options.assert_revision!=="undefined"){return this.getNodeInfo(path,{tid:lock.tid}).then(info=>{if(info.revision!==options.assert_revision){throw new NodeRevisionError(`revision '${info.revision}' does not match requested revision '${options.assert_revision}'`)}if(info.address&&info.address.path===path&&!this.valueFitsInline(value)){return this._writeNodeWithTracking(path,value,{merge:false,tid:tid})}else{return lock.moveToParent().then(parentLock=>{lock=parentLock;return this._writeNodeWithTracking(pathInfo.parentPath,{[pathInfo.key]:value},{merge:true,tid:tid})})}})}else{return lock.moveToParent().then(parentLock=>{lock=parentLock;return this.updateNode(pathInfo.parentPath,{[pathInfo.key]:value},{tid:tid})})}}).then(result=>{lock.release();return result}).catch(err=>{lock.release();throw err})}updateNode(path,updates,options={tid:undefined}){if(typeof updates!=="object"){return Promise.reject(new Error(`invalid updates argument`))}const tid=options&&options.tid||ID.generate();let lock;return this.nodeLocker.lock(path,tid,true,"updateNode").then(l=>{lock=l;return this.getNodeInfo(path,{tid:lock.tid})}).then(nodeInfo=>{const pathInfo=PathInfo.get(path);if(nodeInfo.exists&&nodeInfo.address&&nodeInfo.address.path===path){return this._writeNodeWithTracking(path,updates,{merge:true,tid:tid})}else if(nodeInfo.exists){const pathInfo=PathInfo.get(path);return lock.moveToParent().then(parentLock=>{lock=parentLock;return this._writeNodeWithTracking(pathInfo.parentPath,{[pathInfo.key]:value},{merge:true,tid:tid})})}else{return lock.moveToParent().then(parentLock=>{lock=parentLock;return this.updateNode(pathInfo.parentPath,{[pathInfo.key]:updates},{tid:tid})})}}).then(result=>{lock.release();return result}).catch(err=>{lock.release();throw err})}}module.exports={LocalStorageNodeAddress:LocalStorageNodeAddress,LocalStorageNodeInfo:LocalStorageNodeInfo,LocalStorage:LocalStorage,LocalStorageSettings:LocalStorageSettings}},{"./node-info":33,"./node-value-types":35,"./storage":38,"acebase-core":11}],38:[function(require,module,exports){(function(process){const{Utils:Utils,DebugLogger:DebugLogger,PathInfo:PathInfo,ID:ID,PathReference:PathReference,ascii85:ascii85}=require("acebase-core");const{NodeLocker:NodeLocker}=require("./node-lock");const{VALUE_TYPES:VALUE_TYPES,getValueTypeName:getValueTypeName}=require("./node-value-types");const{NodeInfo:NodeInfo}=require("./node-info");const{EventEmitter:EventEmitter}=require("events");const{cloneObject:cloneObject,compareValues:compareValues,getChildValues:getChildValues,encodeString:encodeString}=Utils;const colors=require("colors");class NodeNotFoundError extends Error{}class NodeRevisionError extends Error{}class ClusterSettings{constructor(settings){settings=settings||{};this.enabled=settings.enabled===true;this.isMaster=settings.isMaster===true;this.master=this.isMaster?null:settings.master;this.workers=this.isMaster?settings.workers:null}}class ClusterManager extends EventEmitter{constructor(settings){super();this.settings=new ClusterSettings(settings);if(!settings.enabled){}else if(settings.isMaster){settings.workers.forEach(worker=>{worker.on("message",data=>{const{id:id,request:request}=data;if(typeof request==="object"&&request.type==="ping"){worker.send({id:id,result:"pong"})}else{const reply=result=>{worker.send({id:id,result:result})};const broadcast=msg=>{console.assert(!("id"in msg),"message to broadcast cannot have id property, it will confuse workers because they think it is a reply to their request");settings.workers.forEach(otherWorker=>{if(otherWorker!==worker){otherWorker.send(msg)}})};this.emit("worker_request",{request:request,reply:reply,broadcast:broadcast})}})});this.request=msg=>{throw new Error(`request can only be called by worker processes!`)}}else{const master=settings.master;const requests={};this.request=msg=>{return new Promise((resolve,reject)=>{const id=ID.generate();requests[id]=resolve;master.send({id:id,request:msg})})};master.on("message",data=>{if(typeof data.id!=="undefined"){let resolve=requests[data.id];delete requests[data.id];resolve(data.result)}else{this.emit("master_notification",data)}});this.request({type:"ping"}).then(result=>{console.log(`PING master process result: ${result}`)})}}get isMaster(){return this.settings.isMaster}get enabled(){return this.settings.enabled}}class StorageSettings{constructor(settings){settings=settings||{};this.maxInlineValueSize=typeof settings.maxInlineValueSize==="number"?settings.maxInlineValueSize:50;this.removeVoidProperties=settings.removeVoidProperties===true;this.cluster=new ClusterSettings(settings.cluster);this.path=settings.path||".";if(this.path.endsWith("/")){this.path=this.path.slice(0,-1)}this.logLevel=settings.logLevel||"log";this.info=settings.info||"realtime database"}}class Storage extends EventEmitter{constructor(name,settings){super();this.name=name;this.settings=settings;this.debug=new DebugLogger(settings.logLevel,`[${name}]`);colors.setTheme({art:["magenta","bold"],intro:["dim"]});const logo=" ___ ______ ".art+"\n"+" / _ \\ | ___ \\ ".art+"\n"+" / /_\\ \\ ___ ___| |_/ / __ _ ___ ___ ".art+"\n"+" | _ |/ __/ _ \\ ___ \\/ _` / __|/ _ \\".art+"\n"+" | | | | (_| __/ |_/ / (_| \\__ \\ __/".art+"\n"+" \\_| |_/\\___\\___\\____/ \\__,_|___/\\___|".art+"\n"+(settings.info?"".padStart(40-settings.info.length," ")+settings.info.magenta+"\n":"");this.debug.write(logo);this.nodeCache={find(path){return null},update(path,info){}};this.nodeLocker=new NodeLocker;this.cluster=new ClusterManager(settings.cluster);const{DataIndex:DataIndex,ArrayIndex:ArrayIndex,FullTextIndex:FullTextIndex,GeoIndex:GeoIndex}=require("./data-index");const _indexes=[];const storage=this;this.indexes={get supported(){const pfs=require("./promise-fs");return pfs&&pfs.hasFileSystem},create(path,key,options={rebuild:false,type:undefined,include:undefined}){path=path.replace(/\/\*$/,"");const rebuild=options&&options.rebuild===true;const indexType=options&&options.type||"normal";let includeKeys=options&&options.include||[];if(typeof includeKeys==="string"){includeKeys=[includeKeys]}const existingIndex=_indexes.find(index=>index.path===path&&index.key===key&&index.type===indexType&&index.includeKeys.length===includeKeys.length&&index.includeKeys.every((key,index)=>includeKeys[index]===key));if(existingIndex&&rebuild!==true){storage.debug.log(`Index on "/${path}/*/${key}" already exists`.inverse);return Promise.resolve(existingIndex)}const index=existingIndex||(()=>{switch(indexType){case"array":return new ArrayIndex(storage,path,key,{include:options.include,config:options.config});case"fulltext":return new FullTextIndex(storage,path,key,{include:options.include,config:options.config});case"geo":return new GeoIndex(storage,path,key,{include:options.include,config:options.config});default:return new DataIndex(storage,path,key,{include:options.include,config:options.config})}})();if(!existingIndex){_indexes.push(index)}return index.build().then(()=>{return index}).catch(err=>{storage.debug.error(`Index build on "/${path}/*/${key}" failed: ${err.message} (code: ${err.code})`.red);if(!existingIndex){_indexes.splice(_indexes.indexOf(index),1)}throw err})},get(path,key=null){return _indexes.filter(index=>index.path===path&&(key===null||key===index.key))},getAll(targetPath,options={parentPaths:true,childPaths:true}){const pathKeys=PathInfo.getPathKeys(targetPath);return _indexes.filter(index=>{const indexKeys=PathInfo.getPathKeys(index.path+"/*");if(options.parentPaths&&indexKeys.every((key,i)=>{return key==="*"||pathKeys[i]===key})&&[index.key].concat(...index.includeKeys).includes(pathKeys[indexKeys.length])){return true}else if(indexKeys.length{return[key,"*"].includes(indexKeys[i])})})},list(){return _indexes.slice()},load(){_indexes.splice(0);const pfs=require("./promise-fs");if(!pfs||!pfs.readdir){return Promise.resolve()}return pfs.readdir(`${storage.settings.path}/${storage.name}.acebase`).then(files=>{const promises=[];files.forEach(fileName=>{if(fileName.endsWith(".idx")){const p=DataIndex.readFromFile(storage,fileName).then(index=>{_indexes.push(index)}).catch(err=>{storage.debug.error(err)});promises.push(p)}});return Promise.all(promises)}).catch(err=>{storage.debug.error(err)})}};const _subs={};const _supportedEvents=["value","child_added","child_changed","child_removed"];_supportedEvents.push(..._supportedEvents.map(event=>`notify_${event}`));this.subscriptions={add(path,type,callback){if(_supportedEvents.indexOf(type)<0){throw new TypeError(`Invalid event type "${type}"`)}let pathSubs=_subs[path];if(!pathSubs){pathSubs=_subs[path]=[]}pathSubs.push({created:Date.now(),type:type,callback:callback})},remove(path,type=undefined,callback=undefined){let pathSubs=_subs[path];if(!pathSubs){return}while(true){const i=pathSubs.findIndex(ps=>type?ps.type===type:true&&callback?ps.callback===callback:true);if(i<0){break}pathSubs.splice(i,1)}},hasValueSubscribersForPath(path){const valueNeeded=this.getValueSubscribersForPath(path);return!!valueNeeded},getValueSubscribersForPath(path){const pathInfo=new PathInfo(path);const valueSubscribers=[];Object.keys(_subs).forEach(subscriptionPath=>{if(pathInfo.equals(subscriptionPath)||pathInfo.isDescendantOf(subscriptionPath)){let pathSubs=_subs[subscriptionPath];const eventPath=PathInfo.fillVariables(subscriptionPath,path);pathSubs.forEach(sub=>{let dataPath=null;if(sub.type==="value"||sub.type==="notify_value"){dataPath=eventPath}else if((sub.type==="child_changed"||sub.type==="notify_child_changed")&&path!==eventPath){let childKey=PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}else if(["child_added","child_removed","notify_child_added","notify_child_removed"].includes(sub.type)&&pathInfo.isChildOf(eventPath)){let childKey=PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}if(dataPath!==null&&valueSubscribers.findIndex(s=>s.type===sub.type&&s.path===eventPath)<0){valueSubscribers.push({type:sub.type,eventPath:eventPath,dataPath:dataPath,subscriptionPath:subscriptionPath})}})}});return valueSubscribers},getAllSubscribersForPath(path){const pathInfo=PathInfo.get(path);const subscribers=[];Object.keys(_subs).forEach(subscriptionPath=>{if(pathInfo.equals(subscriptionPath)||pathInfo.isDescendantOf(subscriptionPath)||pathInfo.isAncestorOf(subscriptionPath)){let pathSubs=_subs[subscriptionPath];const eventPath=PathInfo.fillVariables(subscriptionPath,path);pathSubs.forEach(sub=>{let dataPath=null;if(sub.type==="value"||sub.type==="notify_value"){dataPath=eventPath}else if(sub.type==="child_changed"||sub.type==="notify_child_changed"){let childKey=path===eventPath||pathInfo.isAncestorOf(eventPath)?"*":PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}else if(["child_added","child_removed","notify_child_added","notify_child_removed"].includes(sub.type)&&(pathInfo.isChildOf(eventPath)||path===eventPath||pathInfo.isAncestorOf(eventPath))){let childKey=path===eventPath||pathInfo.isAncestorOf(eventPath)?"*":PathInfo.getPathKeys(path.slice(eventPath.length).replace(/^\//,""))[0];dataPath=PathInfo.getChildPath(eventPath,childKey)}if(dataPath!==null){subscribers.push({type:sub.type,eventPath:eventPath,dataPath:dataPath,subscriptionPath:subscriptionPath})}})}});return subscribers},trigger(event,path,dataPath,oldValue,newValue){const pathSubscriptions=_subs[path]||[];pathSubscriptions.filter(sub=>sub.type===event).forEach(sub=>{sub.callback(null,dataPath,newValue,oldValue)})}}}get path(){return`${this.settings.path}/${this.name}.acebase`}valueFitsInline(value){const encoding="utf8";if(typeof value==="number"||typeof value==="boolean"||value instanceof Date){return true}else if(typeof value==="string"){if(value.length>this.settings.maxInlineValueSize){return false}const encoded=encodeString(value);return encoded.lengththis.settings.maxInlineValueSize){return false}const encoded=encodeString(value.path);return encoded.length0){hasValueSubscribers=true;let eventPaths=valueSubscribers.map(sub=>{return{path:sub.dataPath,keys:PathInfo.getPathKeys(sub.dataPath)}}).sort((a,b)=>{if(a.keys.lengthb.keys.length)return 1;return 0});let first=eventPaths[0];topEventPath=first.path;if(valueSubscribers.filter(sub=>sub.dataPath===topEventPath).every(sub=>sub.type.startsWith("notify_"))){hasValueSubscribers=false}topEventPath=PathInfo.fillVariables(topEventPath,path)}const writeNode=()=>{if(typeof options._customWriteFunction==="function"){return options._customWriteFunction()}return this._writeNode(path,value,options)};const indexes=this.indexes.getAll(path,{childPaths:true,parentPaths:true}).map(index=>({index:index,keys:PathInfo.getPathKeys(index.path)})).sort((a,b)=>{if(a.keys.lengthb.keys.length){return 1}return 0}).map(obj=>obj.index);if(eventSubscriptions.length===0&&indexes.length===0){return writeNode()}let keysFilter=[];if(indexes.length>0){indexes.sort((a,b)=>{if(typeof a._pathKeys==="undefined"){a._pathKeys=PathInfo.getPathKeys(a.path)}if(typeof b._pathKeys==="undefined"){b._pathKeys=PathInfo.getPathKeys(b.path)}if(a._pathKeys.lengthb._pathKeys.length)return 1;return 0});const topIndex=indexes[0];let topIndexPath=topIndex.path===path?path:PathInfo.fillVariables(`${topIndex.path}/*`,path);if(topIndexPath.lengthindex.path===topIndex.path).forEach(index=>{let keys=[index.key].concat(index.includeKeys);keys.forEach(key=>!keysFilter.includes(key)&&keysFilter.push(key))})}}if(!hasValueSubscribers&&options.merge===true&&keysFilter.length===0){keysFilter=Object.keys(value);if(topEventPath!==path){let trailPath=path.slice(topEventPath.length);keysFilter=keysFilter.map(key=>`${trailPath}/${key}`)}}return this.getNodeInfo(topEventPath,{tid:tid}).then(eventNodeInfo=>{if(!eventNodeInfo.exists){return null}let valueOptions={tid:tid};if(keysFilter.length>0){valueOptions.include=keysFilter}if(topEventPath===""&&typeof valueOptions.include==="undefined"){this.debug.warn(`WARNING: One or more value event listeners on the root node are causing the entire database value to be read to facilitate change tracking. Using "value", "notify_value", "child_changed" and "notify_child_changed" events on the root node are a bad practice because of the significant performance impact`)}return this.getNodeValue(topEventPath,valueOptions)}).then(currentValue=>{topEventData=currentValue;return writeNode()}).then(result=>{let newTopEventData=cloneObject(topEventData);if(newTopEventData===null){newTopEventData=path===topEventPath?value:{}}let modifiedData=newTopEventData;if(path!==topEventPath){let trailPath=path.slice(topEventPath.length).replace(/^\//,"");let trailKeys=PathInfo.getPathKeys(trailPath);while(trailKeys.length>0){let childKey=trailKeys.shift();if(!options.merge&&trailKeys.length===0){modifiedData[childKey]=value}else{if(!(childKey in modifiedData)){modifiedData[childKey]={}}modifiedData=modifiedData[childKey]}}}if(options.merge){Object.keys(value).forEach(key=>{let newValue=value[key];if(newValue!==null){modifiedData[key]=newValue}else{delete modifiedData[key]}})}else if(path===topEventPath){newTopEventData=modifiedData=value}const indexUpdates=[];indexes.map(index=>({index:index,keys:PathInfo.getPathKeys(index.path)})).sort((a,b)=>{if(a.keys.lengthb.keys.length){return-1}return 0}).forEach(({index:index})=>{let pathKeys=PathInfo.getPathKeys(topEventPath);let indexPathKeys=PathInfo.getPathKeys(index.path+"/*");let trailKeys=indexPathKeys.slice(pathKeys.length);let oldValue=topEventData;let newValue=newTopEventData;if(trailKeys.length===0){console.assert(pathKeys.length===indexPathKeys.length,"check logic");const p=index.handleRecordUpdate(topEventPath,oldValue,newValue);indexUpdates.push(p);return}const getAllIndexUpdates=(path,oldValue,newValue)=>{if(oldValue===null&&newValue===null){return[]}let pathKeys=PathInfo.getPathKeys(path);let indexPathKeys=PathInfo.getPathKeys(index.path+"/*");let trailKeys=indexPathKeys.slice(pathKeys.length);if(trailKeys.length===0){console.assert(pathKeys.length===indexPathKeys.length,"check logic");return[{path:path,oldValue:oldValue,newValue:newValue}]}let results=[];let trailPath="";while(trailKeys.length>0){let subKey=trailKeys.shift();if(subKey==="*"){let allKeys=oldValue===null?[]:Object.keys(oldValue);newValue!==null&&Object.keys(newValue).forEach(key=>{if(allKeys.indexOf(key)<0){allKeys.push(key)}});allKeys.forEach(key=>{let childPath=PathInfo.getChildPath(trailPath,key);let childValues=getChildValues(key,oldValue,newValue);let subTrailPath=PathInfo.getChildPath(path,childPath);let childResults=getAllIndexUpdates(subTrailPath,childValues.oldValue,childValues.newValue);results=results.concat(childResults)});break}else{let values=getChildValues(subKey,oldValue,newValue);oldValue=values.oldValue;newValue=values.newValue;if(oldValue===null&&newValue===null){break}trailPath=PathInfo.getChildPath(trailPath,subKey)}}return results};let results=getAllIndexUpdates(topEventPath,oldValue,newValue);results.forEach(result=>{const p=index.handleRecordUpdate(result.path,result.oldValue,result.newValue);indexUpdates.push(p)})});const callSubscriberWithValues=(sub,oldValue,newValue,variables=[])=>{let trigger=true;let type=sub.type;if(type.startsWith("notify_")){type=type.slice("notify_".length)}if(type==="child_changed"&&(oldValue===null||newValue===null)){trigger=false}else if(type==="value"||type==="child_changed"){let changes=compareValues(oldValue,newValue);trigger=changes!=="identical"}else if(type==="child_added"){trigger=oldValue===null&&newValue!==null}else if(type==="child_removed"){trigger=oldValue!==null&&newValue===null}let dataPath=sub.dataPath;variables.forEach((variable,i)=>{const safeVarName=variable.name==="*"?"\\*":variable.name.replace("$","\\$");dataPath=dataPath.replace(new RegExp(`(^|/)${safeVarName}([/[]|$)`),`$1${variable.value}$2`)});trigger&&this.subscriptions.trigger(sub.type,sub.subscriptionPath,dataPath,oldValue,newValue)};const triggerAllEvents=()=>{eventSubscriptions.map(sub=>{const keys=PathInfo.getPathKeys(sub.dataPath);return{sub:sub,keys:keys}}).sort((a,b)=>{if(a.keys.lengthb.keys.length){return-1}return 0}).forEach(({sub:sub})=>{const process=(currentPath,oldValue,newValue,variables=[])=>{let trailPath=sub.dataPath.slice(currentPath.length).replace(/^\//,"");let trailKeys=PathInfo.getPathKeys(trailPath);while(trailKeys.length>0){let subKey=trailKeys.shift();if(typeof subKey==="string"&&(subKey==="*"||subKey[0]==="$")){let allKeys=oldValue===null?[]:Object.keys(oldValue);newValue!==null&&Object.keys(newValue).forEach(key=>{if(allKeys.indexOf(key)<0){allKeys.push(key)}});allKeys.forEach(key=>{const childValues=getChildValues(key,oldValue,newValue);const vars=variables.concat({name:subKey,value:key});if(trailKeys.length===0){callSubscriberWithValues(sub,childValues.oldValue,childValues.newValue,vars)}else{process(`${currentPath}/${subKey}`,childValues.oldValue,childValues.newValue,vars)}});return}else{currentPath=PathInfo.getChildPath(currentPath,subKey);let childValues=getChildValues(subKey,oldValue,newValue);oldValue=childValues.oldValue;newValue=childValues.newValue}}callSubscriberWithValues(sub,oldValue,newValue,variables)};process(topEventPath,topEventData,newTopEventData)})};if(options.waitForIndexUpdates===false){indexUpdates.splice(0)}return Promise.all(indexUpdates).then(()=>{process.nextTick(triggerAllEvents);return result})})}getChildren(path,options={keyFilter:undefined,tid:undefined}){throw new Error(`This method must be implemented by subclass`)}getNodeValue(path,options={include:undefined,exclude:undefined,child_objects:true,tid:undefined}){return this.getNode(path,options).then(node=>{return node.value})}getNode(path,options={include:undefined,exclude:undefined,child_objects:true,tid:undefined}){throw new Error(`This method must be implemented by subclass`)}getNodeInfo(path,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}removeNode(path,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}setNode(path,value,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}updateNode(path,updates,options={tid:undefined}){throw new Error(`This method must be implemented by subclass`)}transactNode(path,callback,options={no_lock:false}){let checkRevision;const tid=ID.generate();const lockPromise=options&&options.no_lock===true?Promise.resolve({tid:tid,release(){}}):this.nodeLocker.lock(path,tid,true,"transactNode");return lockPromise.then(lock=>{let changed=false,changeCallback=(err,path)=>{changed=true};if(options&&options.no_lock){this.subscriptions.add(path,"notify_value",changeCallback)}return this.getNode(path,{tid:tid}).then(node=>{checkRevision=node.revision;let newValue;try{newValue=callback(node.value)}catch(err){this.debug.error(`Error in transaction callback: ${err.message}`)}if(newValue instanceof Promise){return newValue.catch(err=>{this.debug.error(`Error in transaction callback: ${err.message}`)})}return newValue}).then(newValue=>{if(typeof newValue==="undefined"){return}if(options&&options.no_lock){this.subscriptions.remove(path,"notify_value",changeCallback)}if(changed){return Promise.reject(new NodeRevisionError(`Node changed`))}return this.setNode(path,newValue,{assert_revision:checkRevision,tid:lock.tid})}).then(result=>{lock.release();return result}).catch(err=>{lock.release();if(err instanceof NodeRevisionError){console.warn(`node value changed, running again. Error: ${err.message}`);return this.transactNode(path,callback,options)}else{throw err}})})}matchNode(path,criteria,options={tid:undefined}){const tid=options&&options.tid||ID.generate();const checkNode=(path,criteria)=>{if(criteria.length===0){return Promise.resolve(true)}const criteriaKeys=criteria.reduce((keys,cr)=>{if(keys.indexOf(cr.key)<0){keys.push(cr.key)}return keys},[]);const unseenKeys=criteriaKeys.slice();let isMatch=true;let delayedMatchPromises=[];return this.getChildren(path,{tid:tid}).next(childInfo=>{unseenKeys.includes(childInfo.key)&&unseenKeys.splice(unseenKeys.indexOf(childInfo.key),1);const keyCriteria=criteria.filter(cr=>cr.key===childInfo.key).map(cr=>({op:cr.op,compare:cr.compare}));const result=checkChild(childInfo,keyCriteria);isMatch=result.isMatch;delayedMatchPromises.push(...result.promises);if(!isMatch||unseenKeys.length===0){return false}}).then(()=>{if(isMatch){return Promise.all(delayedMatchPromises).then(results=>{isMatch=results.every(res=>res.isMatch)})}}).then(()=>{if(!isMatch){return false}isMatch=unseenKeys.every(key=>{const child=new NodeInfo({key:key,exists:false});const keyCriteria=criteria.filter(cr=>cr.key===key).map(cr=>({op:cr.op,compare:cr.compare}));const result=checkChild(child,keyCriteria);return result.isMatch});return isMatch}).catch(err=>{this.debug.error(`Error matching on "${path}": `,err);throw err})};const checkChild=(child,criteria)=>{const promises=[];const isMatch=criteria.every(f=>{let proceed=true;if(f.op==="!exists"||f.op==="=="&&(f.compare===null||f.compare===undefined)){proceed=!child.exists}else if(f.op==="exists"||f.op==="!="&&(f.compare===null||f.compare===undefined)){proceed=child.exists}else if(!child.exists){proceed=false}else{if(child.address){if(child.valueType===VALUE_TYPES.OBJECT&&["has","!has"].indexOf(f.op)>=0){const op=f.op==="has"?"exists":"!exists";const p=checkNode(child.path,[{key:f.compare,op:op}]).then(isMatch=>{return{key:child.key,isMatch:isMatch}});promises.push(p);proceed=true}else if(child.valueType===VALUE_TYPES.ARRAY&&["contains","!contains"].indexOf(f.op)>=0){const p=this.getNodeValue(child.path,{tid:tid}).then(arr=>{const isMatch=f.op==="contains"?f.compare instanceof Array?f.compare.every(val=>arr.includes(val)):arr.includes(f.compare):f.compare instanceof Array?!f.compare.some(val=>arr.includes(val)):!arr.includes(f.compare);return{key:child.key,isMatch:isMatch}});promises.push(p);proceed=true}else if(child.valueType===VALUE_TYPES.STRING){const p=this.getNodeValue(child.path,{tid:tid}).then(val=>{return{key:child.key,isMatch:this.test(val,f.op,f.compare)}});promises.push(p);proceed=true}else{proceed=false}}else if(child.type===VALUE_TYPES.OBJECT&&["has","!has"].indexOf(f.op)>=0){const has=f.compare in child.value;proceed=has&&f.op==="has"||!has&&f.op==="!has"}else if(child.type===VALUE_TYPES.ARRAY&&["contains","!contains"].indexOf(f.op)>=0){const contains=child.value.indexOf(f.compare)>=0;proceed=contains&&f.op==="contains"||!contains&&f.op==="!contains"}else{const ret=this.test(child.value,f.op,f.compare);if(ret instanceof Promise){promises.push(ret);ret=true}proceed=ret}}return proceed});return{isMatch:isMatch,promises:promises}};return checkNode(path,criteria)}test(val,op,compare){if(op==="<"){return val"){return val>compare}if(op===">="){return val>=compare}if(op==="in"){return compare.indexOf(val)>=0}if(op==="!in"){return compare.indexOf(val)<0}if(op==="like"||op==="!like"){const pattern="^"+compare.replace(/[-[\]{}()+.,\\^$|#\s]/g,"\\$&").replace(/\?/g,".").replace(/\*/g,".*?")+"$";const re=new RegExp(pattern,"i");const isMatch=re.test(val.toString());return op==="like"?isMatch:!isMatch}if(op==="matches"){return compare.test(val.toString())}if(op==="!matches"){return!compare.test(val.toString())}if(op==="between"){return val>=compare[0]&&val<=compare[1]}if(op==="!between"){return valcompare[1]}if(op==="has"||op==="!has"){const has=typeof val==="object"&&compare in val;return op==="has"?has:!has}if(op==="contains"||op==="!contains"){const includes=typeof val==="object"&&val instanceof Array&&val.includes(compare);return op==="contains"?includes:!includes}return false}exportNode(path,stream,options={format:"json"}){if(options&&options.format!=="json"){throw new Error(`Only json output is currently supported`)}const stringifyValue=(type,val)=>{const escape=str=>str.replace(/\\/i,"\\\\").replace(/"/g,'\\"');if(type===VALUE_TYPES.DATETIME){val=`"${val.toISOString()}"`}else if(type===VALUE_TYPES.STRING){val=`"${escape(val)}"`}else if(type===VALUE_TYPES.ARRAY){val=`[]`}else if(type===VALUE_TYPES.OBJECT){val=`{}`}else if(type===VALUE_TYPES.BINARY){val=`"${escape(ascii85.encode(val))}"`}else if(type===VALUE_TYPES.REFERENCE){val=`"${val.path}"`}return val};const queue=[];let outputCount=0;let objStart="",objEnd="";const buffer={output:"",enable:false,promise:null};return this.getNodeInfo(path).then(nodeInfo=>{if(!nodeInfo.exists){stream.write("null")}else if(nodeInfo.type===VALUE_TYPES.OBJECT){objStart="{";objEnd="}"}else if(nodeInfo.type===VALUE_TYPES.ARRAY){objStart="{";objEnd="}"}else{return this.getNodeValue(path).then(value=>{const val=stringifyValue(nodeInfo.type,value);return stream.write(val)})}let p=Promise.resolve();if(objStart){p=stream.write(objStart);if(!(p instanceof Promise)){p=Promise.resolve()}}return p.then(()=>{return this.getChildren(path).next(childInfo=>{if(childInfo.address){queue.push(childInfo)}else{const val=stringifyValue(childInfo.type,childInfo.value);const comma=outputCount>0?",":"";const key=typeof childInfo.index==="number"?`"${childInfo.index}"`:`"${childInfo.key}"`;const output=`${comma}${key}:${val}`;outputCount++;if(buffer.enable){buffer.output+=output}else{const flush=output=>{const p=stream.write(output);if(p instanceof Promise){buffer.enable=true;buffer.promise=p.then(()=>{const buffered=buffer.output;buffer.enable=false;buffer.output="";buffer.promise=null;if(buffered.length>0){return flush(buffered)}});return buffer.promise}};flush(output)}}})})}).then(()=>{return buffer.promise}).then(()=>{const next=()=>{if(queue.length===0){return}const childInfo=queue.shift();const comma=outputCount>0?",":"";const key=typeof childInfo.index==="number"?`"${childInfo.index}"`:`"${childInfo.key}"`;let p=stream.write(`${comma}${key}:`);outputCount++;if(!(p instanceof Promise)){p=Promise.resolve(p)}return p.then(()=>{return this.exportNode(childInfo.address.path,stream)}).then(()=>{return next()})};return next()}).then(()=>{if(objEnd){return stream.write(objEnd)}})}}module.exports={Storage:Storage,StorageSettings:StorageSettings,NodeNotFoundError:NodeNotFoundError,NodeRevisionError:NodeRevisionError}}).call(this,require("_process"))},{"./data-index":39,"./node-info":33,"./node-lock":34,"./node-value-types":35,"./promise-fs":39,_process:43,"acebase-core":11,colors:22,events:40}],39:[function(require,module,exports){},{}],40:[function(require,module,exports){var objectCreate=Object.create||objectCreatePolyfill;var objectKeys=Object.keys||objectKeysPolyfill;var bind=Function.prototype.bind||functionBindPolyfill;function EventEmitter(){if(!this._events||!Object.prototype.hasOwnProperty.call(this,"_events")){this._events=objectCreate(null);this._eventsCount=0}this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;var defaultMaxListeners=10;var hasDefineProperty;try{var o={};if(Object.defineProperty)Object.defineProperty(o,"x",{value:0});hasDefineProperty=o.x===0}catch(err){hasDefineProperty=false}if(hasDefineProperty){Object.defineProperty(EventEmitter,"defaultMaxListeners",{enumerable:true,get:function(){return defaultMaxListeners},set:function(arg){if(typeof arg!=="number"||arg<0||arg!==arg)throw new TypeError('"defaultMaxListeners" must be a positive number');defaultMaxListeners=arg}})}else{EventEmitter.defaultMaxListeners=defaultMaxListeners}EventEmitter.prototype.setMaxListeners=function setMaxListeners(n){if(typeof n!=="number"||n<0||isNaN(n))throw new TypeError('"n" argument must be a positive number');this._maxListeners=n;return this};function $getMaxListeners(that){if(that._maxListeners===undefined)return EventEmitter.defaultMaxListeners;return that._maxListeners}EventEmitter.prototype.getMaxListeners=function getMaxListeners(){return $getMaxListeners(this)};function emitNone(handler,isFn,self){if(isFn)handler.call(self);else{var len=handler.length;var listeners=arrayClone(handler,len);for(var i=0;i1)er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Unhandled "error" event. ('+er+")");err.context=er;throw err}return false}handler=events[type];if(!handler)return false;var isFn=typeof handler==="function";len=arguments.length;switch(len){case 1:emitNone(handler,isFn,this);break;case 2:emitOne(handler,isFn,this,arguments[1]);break;case 3:emitTwo(handler,isFn,this,arguments[1],arguments[2]);break;case 4:emitThree(handler,isFn,this,arguments[1],arguments[2],arguments[3]);break;default:args=new Array(len-1);for(i=1;i0&&existing.length>m){existing.warned=true;var w=new Error("Possible EventEmitter memory leak detected. "+existing.length+' "'+String(type)+'" listeners '+"added. Use emitter.setMaxListeners() to "+"increase limit.");w.name="MaxListenersExceededWarning";w.emitter=target;w.type=type;w.count=existing.length;if(typeof console==="object"&&console.warn){console.warn("%s: %s",w.name,w.message)}}}}return target}EventEmitter.prototype.addListener=function addListener(type,listener){return _addListener(this,type,listener,false)};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.prependListener=function prependListener(type,listener){return _addListener(this,type,listener,true)};function onceWrapper(){if(!this.fired){this.target.removeListener(this.type,this.wrapFn);this.fired=true;switch(arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:var args=new Array(arguments.length);for(var i=0;i=0;i--){if(list[i]===listener||list[i].listener===listener){originalListener=list[i].listener;position=i;break}}if(position<0)return this;if(position===0)list.shift();else spliceOne(list,position);if(list.length===1)events[type]=list[0];if(events.removeListener)this.emit("removeListener",type,originalListener||listener)}return this};EventEmitter.prototype.removeAllListeners=function removeAllListeners(type){var listeners,events,i;events=this._events;if(!events)return this;if(!events.removeListener){if(arguments.length===0){this._events=objectCreate(null);this._eventsCount=0}else if(events[type]){if(--this._eventsCount===0)this._events=objectCreate(null);else delete events[type]}return this}if(arguments.length===0){var keys=objectKeys(events);var key;for(i=0;i=0;i--){this.removeListener(type,listeners[i])}}return this};function _listeners(target,type,unwrap){var events=target._events;if(!events)return[];var evlistener=events[type];if(!evlistener)return[];if(typeof evlistener==="function")return unwrap?[evlistener.listener||evlistener]:[evlistener];return unwrap?unwrapListeners(evlistener):arrayClone(evlistener,evlistener.length)}EventEmitter.prototype.listeners=function listeners(type){return _listeners(this,type,true)};EventEmitter.prototype.rawListeners=function rawListeners(type){return _listeners(this,type,false)};EventEmitter.listenerCount=function(emitter,type){if(typeof emitter.listenerCount==="function"){return emitter.listenerCount(type)}else{return listenerCount.call(emitter,type)}};EventEmitter.prototype.listenerCount=listenerCount;function listenerCount(type){var events=this._events;if(events){var evlistener=events[type];if(typeof evlistener==="function"){return 1}else if(evlistener){return evlistener.length}}return 0}EventEmitter.prototype.eventNames=function eventNames(){return this._eventsCount>0?Reflect.ownKeys(this._events):[]};function spliceOne(list,index){for(var i=index,k=i+1,n=list.length;k1){for(var i=1;i=len)return x;switch(x){case"%s":return String(args[i++]);case"%d":return Number(args[i++]);case"%j":try{return JSON.stringify(args[i++])}catch(_){return"[Circular]"}default:return x}}));for(var x=args[i];i=3)ctx.depth=arguments[2];if(arguments.length>=4)ctx.colors=arguments[3];if(isBoolean(opts)){ctx.showHidden=opts}else if(opts){exports._extend(ctx,opts)}if(isUndefined(ctx.showHidden))ctx.showHidden=false;if(isUndefined(ctx.depth))ctx.depth=2;if(isUndefined(ctx.colors))ctx.colors=false;if(isUndefined(ctx.customInspect))ctx.customInspect=true;if(ctx.colors)ctx.stylize=stylizeWithColor;return formatValue(ctx,obj,ctx.depth)}exports.inspect=inspect;inspect.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]};inspect.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"};function stylizeWithColor(str,styleType){var style=inspect.styles[styleType];if(style){return"["+inspect.colors[style][0]+"m"+str+"["+inspect.colors[style][1]+"m"}else{return str}}function stylizeNoColor(str,styleType){return str}function arrayToHash(array){var hash={};array.forEach((function(val,idx){hash[val]=true}));return hash}function formatValue(ctx,value,recurseTimes){if(ctx.customInspect&&value&&isFunction(value.inspect)&&value.inspect!==exports.inspect&&!(value.constructor&&value.constructor.prototype===value)){var ret=value.inspect(recurseTimes,ctx);if(!isString(ret)){ret=formatValue(ctx,ret,recurseTimes)}return ret}var primitive=formatPrimitive(ctx,value);if(primitive){return primitive}var keys=Object.keys(value);var visibleKeys=arrayToHash(keys);if(ctx.showHidden){keys=Object.getOwnPropertyNames(value)}if(isError(value)&&(keys.indexOf("message")>=0||keys.indexOf("description")>=0)){return formatError(value)}if(keys.length===0){if(isFunction(value)){var name=value.name?": "+value.name:"";return ctx.stylize("[Function"+name+"]","special")}if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}if(isDate(value)){return ctx.stylize(Date.prototype.toString.call(value),"date")}if(isError(value)){return formatError(value)}}var base="",array=false,braces=["{","}"];if(isArray(value)){array=true;braces=["[","]"]}if(isFunction(value)){var n=value.name?": "+value.name:"";base=" [Function"+n+"]"}if(isRegExp(value)){base=" "+RegExp.prototype.toString.call(value)}if(isDate(value)){base=" "+Date.prototype.toUTCString.call(value)}if(isError(value)){base=" "+formatError(value)}if(keys.length===0&&(!array||value.length==0)){return braces[0]+base+braces[1]}if(recurseTimes<0){if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}else{return ctx.stylize("[Object]","special")}}ctx.seen.push(value);var output;if(array){output=formatArray(ctx,value,recurseTimes,visibleKeys,keys)}else{output=keys.map((function(key){return formatProperty(ctx,value,recurseTimes,visibleKeys,key,array)}))}ctx.seen.pop();return reduceToSingleString(output,base,braces)}function formatPrimitive(ctx,value){if(isUndefined(value))return ctx.stylize("undefined","undefined");if(isString(value)){var simple="'"+JSON.stringify(value).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return ctx.stylize(simple,"string")}if(isNumber(value))return ctx.stylize(""+value,"number");if(isBoolean(value))return ctx.stylize(""+value,"boolean");if(isNull(value))return ctx.stylize("null","null")}function formatError(value){return"["+Error.prototype.toString.call(value)+"]"}function formatArray(ctx,value,recurseTimes,visibleKeys,keys){var output=[];for(var i=0,l=value.length;i-1){if(array){str=str.split("\n").map((function(line){return" "+line})).join("\n").substr(2)}else{str="\n"+str.split("\n").map((function(line){return" "+line})).join("\n")}}}else{str=ctx.stylize("[Circular]","special")}}if(isUndefined(name)){if(array&&key.match(/^\d+$/)){return str}name=JSON.stringify(""+key);if(name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)){name=name.substr(1,name.length-2);name=ctx.stylize(name,"name")}else{name=name.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'");name=ctx.stylize(name,"string")}}return name+": "+str}function reduceToSingleString(output,base,braces){var numLinesEst=0;var length=output.reduce((function(prev,cur){numLinesEst++;if(cur.indexOf("\n")>=0)numLinesEst++;return prev+cur.replace(/\u001b\[\d\d?m/g,"").length+1}),0);if(length>60){return braces[0]+(base===""?"":base+"\n ")+" "+output.join(",\n ")+" "+braces[1]}return braces[0]+base+" "+output.join(", ")+" "+braces[1]}function isArray(ar){return Array.isArray(ar)}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return isObject(re)&&objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return isObject(d)&&objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return isObject(e)&&(objectToString(e)==="[object Error]"||e instanceof Error)}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=require("./support/isBuffer");function objectToString(o){return Object.prototype.toString.call(o)}function pad(n){return n<10?"0"+n.toString(10):n.toString(10)}var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function timestamp(){var d=new Date;var time=[pad(d.getHours()),pad(d.getMinutes()),pad(d.getSeconds())].join(":");return[d.getDate(),months[d.getMonth()],time].join(" ")}exports.log=function(){console.log("%s - %s",timestamp(),exports.format.apply(exports,arguments))};exports.inherits=require("inherits");exports._extend=function(origin,add){if(!add||!isObject(add))return origin;var keys=Object.keys(add);var i=keys.length;while(i--){origin[keys[i]]=add[keys[i]]}return origin};function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}}).call(this,require("_process"),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./support/isBuffer":44,_process:43,inherits:41}]},{},[32]); \ No newline at end of file