entropic-bond 1.53.0 → 1.53.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"entropic-bond.js","sources":["../src/observable/observable.ts","../node_modules/uuid/dist/esm-browser/stringify.js","../node_modules/uuid/dist/esm-browser/rng.js","../node_modules/uuid/dist/esm-browser/native.js","../node_modules/uuid/dist/esm-browser/v4.js","../src/persistent/persistent.ts","../src/persistent/entropic-component.ts","../src/store/model.ts","../src/store/store.ts","../src/store/data-source.ts","../src/store/json-data-source.ts","../src/cloud-storage/cloud-storage.ts","../src/cloud-storage/mock-cloud-storage.ts","../src/cloud-storage/stored-file.ts","../src/auth/auth.ts","../src/auth/auth-mock.ts","../src/cloud-functions/cloud-functions.ts","../src/cloud-functions/cloud-functions-mock.ts","../src/server-auth/server-auth.ts","../src/server-auth/server-auth-mock.ts","../src/utils/utils.ts"],"sourcesContent":["export type Callback<T> = ( event: T ) => void\nexport type Unsubscriber = ()=>void\n\n/**\n * Implements the Observer pattern.\n * The Observable class is used to notify a list of subscribers when an event occurs.\n * The subscribers are callback functions that are called when the event occurs.\n * The event is passed as a parameter to the callback function.\n * @example\n * // Create an observable\n * const observable = new Observable<number>()\n * // Subscribe a listener\n * const unsubscribe = observable.subscribe( event => console.log( event ) )\n * // Notify the subscribers\n * observable.notify( 1 )\n * // Unsubscribe the listener\n * unsubscribe()\n */\nexport class Observable<T> {\n\n\t/**\n\t * Subscribes a listener callback function. On every notification, \n\t * the listener callback will be called with an event as a parameter if sent.\n\t * \n\t * @param callback the listener callback\n\t * @returns a function to unsubscribe the listener from further notifications\n\t */\n\t subscribe( callback: Callback<T> ): Unsubscriber {\n\t\tthis.subscribers.add(callback)\n\t\treturn ()=>this.unsubscribe( callback )\n\t}\n\n\t/**\n\t * Removes the callback from the notification list.\n\t * \n\t * @param listenerCallback the listener callback to remove\n\t */\n\tunsubscribe( callback: Callback<T> ) {\n\t\tthis.subscribers.delete( callback )\n\t}\n\n\t/**\n\t * Notifies all the subscribers with the event passed as parameter.\n\t * \n\t * @param event the event passed to all subscribers.\n\t */\n\tnotify( event?: T ) {\n\t\tthis.subscribers.forEach(subs => subs(event!))\n\t}\n\n\t/**\n\t * Returns the number of subscribers.\n\t * \n\t * @returns the number of subscribers\n\t * @example\n\t * const observable = new Observable<number>()\n\t * observable.subscribe( event => console.log( event ) )\n\t * observable.subscribe( event => console.log( event ) )\n\t * observable.subscribe( event => console.log( event ) )\n\t * console.log( observable.subscribersCount ) // 3\n\t */\n\tget subscribersCount() {\n\t\treturn this.subscribers.size\n\t}\n\n\tprivate subscribers: Set<Callback<T>> = new Set()\n}","import validate from './validate.js';\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n //\n // Note to future-self: No, you can't remove the `toLowerCase()` call.\n // REF: https://github.com/uuidjs/uuid/pull/677#issuecomment-1757351351\n return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n var uuid = unsafeStringify(arr, offset);\n // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;","// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\n\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n return getRandomValues(rnds8);\n}","var randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);\nexport default {\n randomUUID\n};","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n offset = offset || 0;\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;","import { v4 as uuid } from 'uuid'\nimport { ClassPropNames, ClassPropNamesOfType, Primitive, SomeClassProps, UnderscoredProp } from '../types/utility-types'\n\nexport type PersistentConstructor = new () => Persistent\n\ninterface FactoryMap {\n\t[ id: string ]: {\n\t\tfactory: PersistentConstructor\n\t\tannotation: unknown\n\t}\n}\n\n/**\n * The corresponding type of the plain object of a persistent class.\n */\nexport type PersistentObject<T extends Persistent> = Omit<SomeClassProps<T>, 'className'> & Partial<DocumentReference> & {\n\t__className: string\n\t__rootCollections?: Collections\n}\n\nexport type PersistentObjectWithId<T extends Persistent> = PersistentObject<T> & {\n\tid: string\n}\n\n/**\n * The type of the plain object of a persistent class for all the nested properties.\n */\nexport type MakePersistentObjects<T> = {\n [A in keyof T]: T[A] extends Persistent? PersistentObject<T[A]> : MakePersistentObjects<T[A]>\n}\n\n/**\n * A collection of document objects typically returned by Persistent.toObject()\n * @see Persistent.toObject\n */\nexport type Collections = {\n\t[ collectionPath: string ]: PersistentObjectWithId<Persistent>[] | undefined\n}\n\n/**\n * Stores information about a reference in another collection.\n */\nexport interface DocumentReference {\n\tid: string\n\t__className: string\n\t__documentReference: {\n\t\tstoredInCollection: string\n\t}\n}\n\ntype PersistentPropertyCollection = {\n\t[className: string]: PersistentProperty[]\n}\n\n/**\n * A class that provides several methods to serialize and deserialize objects.\n */\nexport class Persistent {\n\n\t/**\n\t * Registers a class to be used by the persistence engine.\n\t * @param className the name of the class to be registered\n\t * @param factory the constructor of the registered class\n\t * @param annotation an annotation associated with the class\n\t */\n\tstatic registerFactory( className: string, factory: PersistentConstructor, annotation?: unknown ) {\n\t\tthis._factoryMap[ className ] = { factory, annotation }\n\t}\n\n\t/**\n\t * Returns the constructor of a registered class\n\t * @param className the name of the class to be retrieved\n\t * @returns the constructor of the class\n\t * @throws an error if the class is not registered\n\t * @see registerFactory\n\t * @see registeredClasses\n\t * @see classesExtending\n\t * @see annotations\n\t */\n\tstatic classFactory( className: string | undefined ) {\n\t\tif ( !className ) throw new Error( `You should provide a class name.` )\n\t\tif ( !this._factoryMap[ className ] ) throw new Error( `You should register class ${ className } prior to use.` )\n\t\treturn this._factoryMap[ className ]!.factory\n\t}\n\n\t/**\n\t * Returns the names of all registered classes\n\t * @returns the names of all registered classes\n\t * @see registerFactory\n\t * @see classFactory\n\t */\n\tstatic registeredClasses() {\n\t\treturn Object.keys( this._factoryMap )\n\t}\n\n\t/**\n\t * Returns the names of all registered classes that extend a given class\n\t * @param derivedFrom the class to be extended\n\t * @returns the names of all registered classes that extend the given class\n\t * @see registerFactory\n\t * @see classFactory\n\t */\n\tstatic classesExtending( derivedFrom: PersistentConstructor | Function ) {\n\t\treturn Object.entries( this._factoryMap )\n\t\t\t.filter(([ , obj ]) => new ( obj.factory ) instanceof derivedFrom )\n\t\t\t.map(([ className ]) => className )\n\t}\n\n\t/**\n\t * Returns the annotation associated with a registered class\n\t * @param className the name of the class to be retrieved\n\t * @returns the annotation associated with the class\n\t * @throws an error if the class is not registered\n\t * @see registerFactory\n\t */\n\tstatic annotations( className: string | Persistent | PersistentConstructor ) {\n\t\tif ( className instanceof Persistent ) className = className.className\n\t\telse if ( typeof className === 'string' ) className\n\t\telse className = new className().className\n\n\t\tif ( !this._factoryMap[ className ] ) throw new Error( `You should register class ${ className } prior to use.` )\n\t\treturn this._factoryMap[ className ]!.annotation\n\t}\n\n\t/**\n\t * Returns a new instance of Persistent class.\n\t * @param className the initial id of this instance. If not provided, a new id will be generated\n\t */\n\tconstructor( id: string = uuid() ) {\n\t\tthis._id = id\n\t}\n\n\t/**\n\t * Gets the class name of this instance.\n\t */\n\tget className(): string {\n\t\treturn this[ '__className' ];\n\t}\n\n\t/**\n\t * Sets the id of this instance.\n\t * @param value the id of this instance\n\t */\n\tprotected setId( value: string ) {\n\t\tthis._id = value\n\t}\n\n\t/**\n\t * Returns the id of this instance.\n\t * @returns the id of this instance\n\t */\n\tget id() {\n\t\treturn this._id;\n\t}\n\n\t/**\n\t * This method is called by the persistence engine when the instance has been\n\t * just serialized. It is called after the properties are initialized with \n\t * serialized data.\n\t */\n\tprotected afterDeserialize() {}\n\n\t/**\n\t * This method is called by the persistence engine before the instance is\n\t * serialized. \n\t */\n\tprotected beforeSerialize() {}\n\n\t/**\n\t * Returns an array of the persistent properties of this instance.\n\t * @returns an array of the persistent properties of this instance\n\t */\n\tgetPersistentProperties(): readonly PersistentProperty[] {\n\t\tif ( !this._persistentProperties ) return []\n\t\treturn this._persistentProperties.map( prop => ({\n\t\t\t...prop,\n\t\t\tname: prop.name.slice( 1 ) \n\t\t}))\n\t}\n\n\t/**\n\t * Get the property information of this instance\n\t * @param propName the persistent property name\n\t * @returns the property information\n\t */\n\tgetPropInfo<T extends this>( propName: ClassPropNames<T> ): PersistentProperty {\n\t\tconst propInfo = this.getPersistentProperties().find( prop => prop.name === propName as string )\n\t\tif ( !propInfo ) throw new Error( `Property \"${ propName as string }\" has not been registered.` )\n\t\treturn propInfo\n\t}\n\n\t/**\n\t * Query if the property is required\n\t * To mark a property as required, use the @required decorator\n\t * @param propName the persistent property name\n\t * @returns true if the property is required\n\t * @see required\n\t */\n\tisRequired<T extends this>( propName: ClassPropNames<T> ): boolean {\n\t\tconst validator = this.getPropInfo( propName ).validator\n\t\treturn validator !== undefined && validator !== null\n\t}\n\n\t/**\n\t * Query if the property value is valid\n\t * Define the validator function using the @required decorator\n\t * @param propName the persistent property name\n\t * @returns true if the property value is valid using the validator function\n\t * passed to the @required decorator\n\t * @see required\n\t */\n\tisPropValueValid<T extends this>( propName: ClassPropNames<T> ): boolean {\n\t\tconst propInfo = this.getPropInfo( propName )\n\t\tif ( !propInfo.validator ) return true\n\t\treturn propInfo.validator( this[ propInfo.name ], propInfo, this )\n\t}\n\n\t/**\n\t * Copy the persistent properties of the given instance to this instance. \n\t * The property `id` will be ignored.\n\t * Only the properties that are not null or undefined will be copied.\n\t * @param instance the instance to be copied\n\t * @returns this instance\n\t * @see fromObject\n\t * @see toObject\n\t */\n\tclone( instance: Persistent ): this {\n\t\tconst obj = instance.toObject() as any\n\t\tdelete obj['id']\n\t\treturn this.fromObject( obj )\n\t}\n\n\t/**\n\t * Initializes the persistent properties of this instance from the properties \n\t * of given object.\n\t * @param obj the object to be copied\n\t * @returns this instance\n\t * @see clone\n\t * @see toObject\n\t */\n\tfromObject( obj: Partial<PersistentObject<this>> |{}): this {\n\t\tthis.fromObj( obj )\n\t\tthis.afterDeserialize()\n\n\t\treturn this\n\t}\n\n\tprivate fromObj( obj: Partial<PersistentObject<this>> | {}) {\n\t\tif ( !this._persistentProperties ) return this\n\n\t\tthis._persistentProperties.forEach( prop => {\n\t\t\tconst propName = this.removeUnderscore( prop )\n\n\t\t\tconst value = obj[ propName ]\n\t\t\tif ( value !== undefined && value !== null ) {\n\t\t\t\tthis[ prop.name ] = this.fromDeepObject( value )\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Returns a plain object representation of this instance.\n\t * Only the properties that are not null or undefined will be copied.\n\t * @returns a plain object representation of this instance\n\t * @see fromObject\n\t * @see clone\n\t */\n\ttoObject(): PersistentObject<this> {\n\t\tconst rootCollections: Collections = {}\n\t\tconst obj = this.toObj( rootCollections )\n\t\tthis.pushDocument( rootCollections, this.className, obj )\n\n\t\treturn {\n\t\t\t...obj,\n\t\t\t__rootCollections: rootCollections\n\t\t}\n\t}\n\n\tprivate toObj( rootCollections: Collections ): PersistentObject<this> {\n\t\tif ( !this._persistentProperties ) return {} as PersistentObject<this>\n\t\tthis.beforeSerialize()\n\n\t\tconst obj: PersistentObject<this> = {} as any\n\t\tif ( !this.className ) throw new Error( 'You should register this class prior to streaming it.' )\n\n\t\tthis._persistentProperties.forEach( prop => {\n\t\t\tconst propValue = this[ prop.name ]\n\t\t\tconst propName = this.removeUnderscore( prop )\n\t\t\t\n\t\t\tif ( propValue !== undefined && propValue !== null ) {\n\n\t\t\t\tif ( prop.isReference ) {\n\t\t\t\t\tobj[ propName ] = this.toReferenceObj( prop, rootCollections )\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tobj[ propName ] = this.toDeepObj( propValue, rootCollections )\n\t\t\t\t}\n\n\t\t\t\tif ( prop.searchableArray ) {\n\t\t\t\t\tobj[ Persistent.searchableArrayNameFor( propName ) ] = propValue.map(( value: PersistentObject<Persistent> ) => value.id )\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tobj[ '__className' ] = this.className\n\n\t\treturn obj\n\t}\n\n\tstatic searchableArrayNameFor( propName: string ) {\n\t\treturn `__${ propName }_searchable`\n\t}\n\n\tprivate fromDeepObject( value: unknown ) {\n\t\tif ( value === undefined || value === null ) return value\n\t\t\n\t\tif ( Array.isArray( value ) ) {\n\t\t\treturn value.map( item => this.fromDeepObject( item ) )\n\t\t}\n\n\t\tif ( value[ '__documentReference' ] ) {\n\t\t\tconst ref: DocumentReference = value as DocumentReference\n\t\t\tconst emptyInstance = Persistent.createInstance( ref )\n\t\t\t// emptyInstance._id = ref.id\n\t\t\temptyInstance['__documentReference'] = value[ '__documentReference' ]\n\t\t\treturn emptyInstance\n\t\t}\n\n\t\tif ( value[ '__className' ] ) {\n\t\t\treturn Persistent.createInstance( value as PersistentObject<Persistent> )\n\t\t}\n\n\t\tif ( typeof value === 'object' ) {\n\t\t\tconst newObject = {}\n\n\t\t\tObject.entries( value ).forEach(\n\t\t\t\t( [ key, value ] ) => newObject[ key ] = this.fromDeepObject( value )\n\t\t\t)\n\n\t\t\treturn newObject\n\t\t}\n\n\t\treturn value\n\t}\n\n\tprivate toDeepObj( value: any, rootCollections: Collections ) {\n\t\tif ( value === null || value === undefined ) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tif ( Array.isArray( value ) ) {\n\t\t\treturn value.map( item => this.toDeepObj( item, rootCollections ) )\n\t\t}\n\n\t\tif ( value[ '__documentReference' ] ) return value\n\t\t\n\t\tif ( value instanceof Persistent ) {\n\t\t\treturn value.toObj( rootCollections )\n\t\t}\n\n\t\tif ( typeof value === 'object' ) {\n\t\t\tconst newObject = {}\n\n\t\t\tObject.entries( value ).forEach(\n\t\t\t\t( [ key, val ] ) => newObject[ key ] = this.toDeepObj( val, rootCollections )\n\t\t\t)\n\n\t\t\treturn newObject\n\t\t}\n\n\t\treturn value\n\t}\n\n\tstatic collectionPath( ownerInstance: Persistent, prop: PersistentProperty ) {\n\t\tlet storeInCollection: string\n\n\t\tif ( typeof prop.storeInCollection === 'function' ) {\n\t\t\tstoreInCollection = prop.storeInCollection( ownerInstance, prop )\n\t\t}\n\t\telse {\n\t\t\tstoreInCollection = prop.storeInCollection ?? ownerInstance.className\n\t\t}\n\t\treturn storeInCollection\n\t}\n\n\tprivate toReferenceObj( prop: PersistentProperty, rootCollections: Collections ) {\n\t\tconst propValue: Persistent | Persistent[] = this[ prop.name ]\n\t\t\n\t\tif ( Array.isArray( propValue ) ) {\n\n\t\t\treturn propValue.map( item => {\n\t\t\t\tif ( !prop.isPureReference ) {\n\t\t\t\t\tthis.pushDocument( rootCollections, Persistent.collectionPath( item, prop ), item )\n\t\t\t\t}\n\t\t\t\treturn this.buildRefObject( item, Persistent.collectionPath( item, prop ), prop.cachedProps )\n\t\t\t})\n\n\t\t}\n\t\telse {\n\t\t\tif ( !prop.isPureReference ) {\n\t\t\t\tthis.pushDocument( rootCollections, Persistent.collectionPath( propValue, prop ), propValue )\n\t\t\t}\n\t\t\treturn this.buildRefObject( propValue, Persistent.collectionPath( propValue, prop ), prop.cachedProps )\n\n\t\t}\n\t}\n\n\tprivate buildRefObject( value: Persistent, storeInCollection: string, cachedProps?: ClassPropNames<Persistent>[] ): DocumentReference {\n\t\tconst forcedObject = cachedProps?.reduce( ( obj, propName ) => {\n\t\t\tif ( value[ propName ] !== undefined ) obj[ propName ] = value[ propName ]\n\t\t\treturn obj\n\t\t}, {})\n\n\t\treturn {\n\t\t\tid: value.id,\n\t\t\t__className: value.className || value['__className'],\n\t\t\t__documentReference: {\n\t\t\t\tstoredInCollection: storeInCollection\n\t\t\t}, \n\t\t\t...forcedObject\t\n\t\t}\n\t}\n\n\tprivate pushDocument( collections: Collections, collectionName: string, value: DocumentReference | Persistent | PersistentObject<this> ) {\n\t\tif ( '__documentReference' in value && value.__documentReference ) return\n\t\t\n\t\tif ( !collections[ collectionName ] ) collections[ collectionName ] = []\n\t\tconst document = this.toDeepObj( value, collections )\n\t\tcollections[ collectionName ]!.push( document )\n\t}\n\n\tprivate removeUnderscore( prop: PersistentProperty ) {\n\t\treturn prop.name.slice(1)\n\t}\n\n\tstatic createReference<T extends Persistent>( obj: PersistentObject<T> | string ): T {\n\t\tconst instance = Persistent.createInstance( obj )\n\t\tinstance['__documentReference'] = obj['__documentReference'] || { storedInCollection: instance.className }\n\t\treturn instance\n\t}\n\n\tstatic createInstance<T extends Persistent>( obj: PersistentObject<T> | string ): T {\n\t\tif ( typeof obj === 'string' ) {\n\t\t\treturn new ( Persistent.classFactory( obj ) ) as T\n\t\t}\n\t\telse {\n\t\t\ttry {\n\t\t\t\tconst instance = new ( Persistent.classFactory( obj.__className ) )\n\t\t\t\treturn instance.fromObject( obj ) as T\n\t\t\t}\n\t\t\tcatch ( e ) {\n\t\t\t\tconst stringifiedObj = Object.entries( obj )\n\t\t\t\t\t.filter(([ _key, value ])=> value !== undefined && value !== null && typeof value !== 'function' )\n\t\t\t\t\t.map(([ key, value ])=>`${ key }: ${ value }` )\n\t\t\t\t\t.join( ',\\n\\t' )\n\t\t\t\tthrow new Error( `${ e }\\n-----> Class name not found in object:\\n{\\n\\t ${ stringifiedObj } \\n}\\n` )\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic propInfo<T extends Persistent>( registeredClassName: string, propName: ClassPropNames<T> ): PersistentProperty {\n\t\tconst inst = Persistent.createInstance( registeredClassName )\n\t\treturn inst.getPropInfo( propName )\n\t}\n\n\t/**\n\t * Retrieves a collection of references with the properties that are stored in the reference object\n\t * @returns the references collection\n\t */\n\tstatic getSystemRegisteredReferencesWithCachedProps(): PersistentPropertyCollection {\n\t\tconst systemRegisteredClasses = Persistent.registeredClasses()\n\t\tconst referencesWithStoredProps = systemRegisteredClasses.reduce(( referencesWithStoredProps, className ) => {\n\t\t\tconst inst = Persistent.createInstance( className )\n\t\t\tconst propsWithStoredValue = inst.getPersistentProperties().filter( \n\t\t\t\tpropInfo => propInfo.cachedProps\n\t\t\t)\n\t\t\tif ( propsWithStoredValue.length > 0 ) referencesWithStoredProps[className] = propsWithStoredValue\n\t\t\treturn referencesWithStoredProps\n\t\t}, {} as PersistentPropertyCollection )\n\t\t\n\t\treturn referencesWithStoredProps\n\t}\n\n\t@persistent private _id: string\n\tprivate _persistentProperties: PersistentProperty[] | undefined\n\tprivate static _factoryMap: FactoryMap = {}\n}\n\n///////////////////////////////////\n//Decorators\n///////////////////////////////////\n\ntype CollectionPathCallback = ( value: Persistent, prop: PersistentProperty ) => string\ntype ValidatorFunction<T extends Persistent, P extends ClassPropNames<T>> = ( value: T[P], property: PersistentProperty, persistentInstance: T ) => boolean\n\nexport interface PersistentProperty {\n\tname: string\n\tisReference?: boolean\n\tisPureReference?: boolean\n\tstoreInCollection?: string | CollectionPathCallback\n\tsubCollection?: string\n\tcachedProps?: ClassPropNames<Persistent>[]\n\ttoObjectSpecial?: ( classObj: any ) => any\n\tfromObjectSpecial?: ( obj: any ) => any\n\tsearchableArray?: boolean\n\tvalidator?: ValidatorFunction<any, any>\n\ttypeName?: string | string[]\n}\n\n/**\n * Decorator for a property that you want to persist.\n */\nexport function persistent( target: Persistent, property: string ) {\n\treturn persistentParser()( target, property );\n}\n\n/**\n * Decorator for a property that is a reference to a persistent object and should be stored\n * in a specific collection.\n * @param collectionPath the path to the collection where the reference should be stored.\n * @returns \n */\nexport function persistentReferenceAt( collectionPath: string | CollectionPathCallback ) {\n\treturn function( target: Persistent, property: string ) {\n\t\treturn persistentParser({ \n\t\t\tstoreInCollection: collectionPath,\n\t\t\tisReference: true\n\t\t})( target, property )\n\t}\n}\n\n/**\n * Decorator for a property that is a reference to a persistent object. \n * The reference content is automatically stored in a collection. The collection \n * is determined by the class name of the decorated property. \n * @see persistentPureReference\n */\nexport function persistentReference( target: Persistent, property: string ) {\n\treturn persistentParser({ isReference: true })( target, property )\n}\n\n/**\n * Decorator to declare a persistent reference (see @persistentReference) that stores\n * the values in cachedProps as values in the reference object. This is useful\n * when you are not able to wait for population of referenced properties.\n * @param cachedProps the properties whose values should be stored in the reference object\n * @param storedInCollection indicates the path of the collection where this reference is stored\n */\nexport function persistentReferenceWithCachedProps<T extends Persistent>( cachedProps: ClassPropNamesOfType<T, Primitive>[], storeInCollection?: string | CollectionPathCallback, propTypeName?: string | string[] ) {\n\treturn function( target: Persistent, property: string ) {\n\t\tconst persistentProps: Partial<PersistentProperty> = { \n\t\t\tisReference: true, \n\t\t\tcachedProps: cachedProps as ClassPropNames<Persistent>[],\n\t\t\tstoreInCollection: storeInCollection,\n\t\t\ttypeName: propTypeName\n\t\t}\n\t\treturn persistentParser( persistentProps )( target, property )\n\t}\n}\n\n/**\n * Decorator for a property that is a reference to a persistent object. \n * In this case, and contrary to the @persistentReference decorator, the reference \n * contents is not stored even it has been changed. Only the reference information \n * is stored.\n * @see persistentReference\n */\n export function persistentPureReference( target: Persistent, property: string, storeInCollection?: string | CollectionPathCallback ) {\n\treturn persistentParser({ isReference: true, isPureReference: true, storeInCollection })( target, property )\n}\n\n/**\n * Decorator to declare a persistent property as a pure reference (see @persistentPureReference) that stores\n * the values of the properties listed in cachedProps as values in the reference object. This is useful\n * when you only need a few properties to be available without needing to populate the referenced property.\n * @param cachedProps the properties whose values should be stored in the reference object\n * @param storedInCollection indicates the path of the collection where this reference is stored\n * @see persistentReferenceWithCachedProps\n * @see persistentPureReference\n * @sample\n * class User extends Persistent {\n * \t@persistentPureReferenceWithCachedProps( ['name', 'email'] ) private _friend: User\n * }\n * // the reference object will contain the properties name and email of the referenced user\n * // without having to populate the _friend property\n */\nexport function persistentPureReferenceWithCachedProps<T extends Persistent>( cachedProps: ClassPropNamesOfType<T,Primitive>[], storeInCollection?: string | CollectionPathCallback, propTypeName?: string | string[] ) {\n\treturn function( target: Persistent, property: string ) {\n\t\treturn persistentParser({ \n\t\t\tisReference: true, \n\t\t\tisPureReference: true, \n\t\t\tcachedProps: cachedProps as ClassPropNames<Persistent>[], \n\t\t\tstoreInCollection: storeInCollection,\n\t\t\ttypeName: propTypeName\n\t\t})( target, property )\n\t}\n}\n\nexport function persistentParser( options?: Partial<PersistentProperty> ) {\n\treturn function( target: Persistent, property: string ) {\n\n\t\t// from: https://stackoverflow.com/questions/43912168/typescript-decorators-with-inheritance\n\t\t// should work like this in order to avoid propagation of persistent properties from one class to others\n\t\tif ( !Object.getOwnPropertyDescriptor( target, '_persistentProperties' ) ) {\n\t\t\tif ( target[ '_persistentProperties' ] ) {\n\t\t\t\ttarget[ '_persistentProperties' ] = [ ...target[ '_persistentProperties' ] ]\n\t\t\t}\n\t\t\telse target[ '_persistentProperties' ] = []\n\t\t}\n\n\t\tconst propInfo = target[ '_persistentProperties' ]!.find( prop => prop.name === property )\n\t\tif ( propInfo ) {\n\t\t\tObject.assign( propInfo, options )\n\t\t}\n\t\telse {\n\t\t\ttarget[ '_persistentProperties' ]!.push({\n\t\t\t\tname: property,\n\t\t\t\t...options\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Decorator to register a persistent class. Entropic Bond needs that you register\n * all persistent classes that you want to use in any persistent stream. \n * @param className the name of the class\n * @param annotation an optional annotation that can be used to store additional information\n */\nexport function registerPersistentClass( className: string, annotation?: unknown ) {\n\treturn ( constructor: PersistentConstructor ) => {\n\t\tPersistent.registerFactory( className, constructor, annotation )\n\t\tconstructor.prototype.__className = className\n\t}\n}\n\n/**\n * Decorator to register a legacy name for a persistent class. This is useful when you want to\n * be able to load old data that was stored with a different class name.\n * @param legacyName the legacy name of the class\n */\nexport function registerLegacyClassName( legacyName: string ) {\n\treturn ( constructor: PersistentConstructor ) => {\n\t\tPersistent.registerFactory( legacyName, constructor )\n\t}\n}\n\n/**\n * Decorator to make a `Persistent` array property searchable by the \n * persistance engine.\n * When a property is marked as searchable, the persistance engine will\n * generate internally a new property with the same name but with the suffix `_searchable`\n * and prefixed with the `_` character. This new property will contain an array\n * with the `id` of the persistent elements in the original array.\n */ \nexport function searchableArray( target: Persistent, property: string ) {\n\treturn persistentParser({ searchableArray: true })( target, property )\n}\n\n/**\n * Decorator to mark the property as required.\n * @see requiredWithValidator\n */\nexport function required( target: Persistent, property: string ) {\n\treturn persistentParser({ validator: ( value: any ) => value !== undefined && value !== null })( target, property )\n}\n\n/**\n * Decorator to mark the property as required.\n * @param validator a function that returns true if the property value is valid. \n * By default, the property is valid if it is not undefined and not null.\n * @see required\n */\nexport function requiredWithValidator<T extends Persistent, P extends ClassPropNames<T>>( validator: ValidatorFunction<T, P> = ( value: T[P] ) => value !== undefined && value !== null ) {\n\treturn function( target: T, property: UnderscoredProp<P> ) {\n\t\treturn persistentParser({ validator: validator })( target, property )\n\t}\n}\n","import { Callback, Observable, Unsubscriber } from '../observable/observable';\nimport { ClassArrayPropNames, ClassProps, Elements } from '../types/utility-types';\nimport { Persistent } from './persistent';\n\nexport type PropChangeEvent<T> = Partial<ClassProps<T>>\nexport type PropChangeCallback<T> = Callback<PropChangeEvent<T>>\ntype ArrayPropsElem<T> = Elements<T[ClassArrayPropNames<T>]>\nexport type CompareFunction<T> = ( a: ArrayPropsElem<T>, b: ArrayPropsElem<T> )=>boolean\n\n/**\n * Derived classes from EntropicComponent will have the ability to notify \n * property changes by calling one of the provided notification methods.\n * It extends Persistent class therefore EntropicComponent children will have\n * persistance through the Entropic Bond persistence mechanism\n */\nexport class EntropicComponent extends Persistent {\n\n\t/**\n\t * Subscribes a listener callback function. Every time a property is changed, \n\t * the listener callback will be called with the property change event.\n\t * \n\t * @param listenerCallback the listener callback\n\t * @returns a function to unsubscribe the listener from further notifications\n\t */\n\tonChange( listenerCallback: PropChangeCallback<this> ): Unsubscriber {\n\t\treturn this._onChange.subscribe( listenerCallback )\n\t}\n\n\t/**\n\t * Removes the listener callback subscrition from the notifications.\n\t * \n\t * @param listenerCallback the listener callback to remove\n\t */\n\tremoveOnChange( listenerCallback: PropChangeCallback<this> ) {\n\t\tthis._onChange.unsubscribe( listenerCallback )\n\t}\n\n\t/**\n\t * Changes the value of the property and notifies the subscribers about the change.\n\t * This is a helper method that can be used in the property setter.\n\t * \n\t * @param propName the name of the property to be changed\n\t * @param value the new value for the property\n\t * @returns true in case the property has been effectively changed, false otherwise\n\t */\n\tprotected changeProp<P extends keyof this>( propName: P, value: this[ P ] ): boolean {\n\t\tconst pName = '_' + String( propName );\n\n\t\tif ( this[ pName ] !== value ) {\n\t\t\tthis[ pName ] = value;\n\t\t\tthis._onChange.notify({ [ propName ]: value });\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Notifies the subscribers a property or group of properties change.\n\t * This is a helper function to be used when you want to notify property changes.\n\t * \n\t * @param event the event with the changed properties\n\t */\n\tprotected notify<T extends EntropicComponent>( event: PropChangeEvent<T> ) {\n\t\tthis._onChange.notify(event)\n\t}\n\n\t/**\n\t * Inserts a new element in an arbitrary array property of this class and \n\t * fires a change event if successfully inserted. To avoid repeated elements\n\t * to be inserted, you can pass a function that checks for inequity.\n\t * \n\t * @param arrayPropName the name of the array property of this class where you\n\t * \t\t\t\t\t\t\t\t\t\t\twant to insert the\tnew element.\n\t * @param element the element to be inserted\n\t * @param isUnique a function that checks for inequity of the two elements \n\t * \t\t\t\t\t\t\t\t\tpassed as parameter. If the returned value is true, the \n\t * \t\t\t\t\t\t\t\t\tvalue will be\tpushed into the array. When the function is \n\t * \t\t\t\t\t\t\t\t\tnot provided, the element will be inserted regardless it is\n\t * \t\t\t\t\t\t\t\t\talready in the array.\n\t * @returns the inserted element or undefined if the element was not inserted.\n\t */\n\tprotected pushAndNotify<T extends EntropicComponent>( \n\t\tarrayPropName: ClassArrayPropNames<T>, \n\t\telement: ArrayPropsElem<T>, \n\t\tisUnique?: CompareFunction<T> \n\t): ArrayPropsElem<T> | undefined {\n\n\t\tconst pName = '_' + String( arrayPropName );\n\t\tconst alreadyIn = isUnique && this[ pName ].find( \n\t\t\t( item: ArrayPropsElem<T> ) => !isUnique( item, element ) \n\t\t)\n\t\tif ( alreadyIn ) return undefined\n\n\t\tthis[ pName ].push( element )\n\t\tthis.notify({ [arrayPropName]: this[ arrayPropName as string ] })\n\t\treturn element\n\t}\n\n\t/**\n\t * Removes an element from an arbitrary array property of this class and fires\n\t * a change event on operation success.\n\t * \n\t * @param arrayPropName the name of the array property of this class where you\n\t * \t\t\t\t\t\t\t\t\t\t\twant to insert the\tnew element.\n\t * @param element the element to be inserted\n\t * @param isEqual a function that checks for equity of the two elements \n\t * \t\t\t\t\t\t\t\t\tpassed as parameter. If the returned value is true, the \n\t * \t\t\t\t\t\t\t\t\tvalue will be\tremoved from the array. \n\t * @returns the removed element or undefined if the element was not removed.\n\t */\n\tprotected removeAndNotify<T extends EntropicComponent>( \n\t\tarrayPropName: ClassArrayPropNames<T>, \n\t\telement: ArrayPropsElem<T>,\n\t\tisEqual: CompareFunction<T>\n\t): ArrayPropsElem<T> | undefined {\n\n\t\tconst pName = '_' + String( arrayPropName );\n\n\t\tconst originalLength = this[ pName ].length\n\n\t\tthis[ pName ] = this[ pName ].filter( \n\t\t\t( item: ArrayPropsElem<T> ) => !isEqual( item, element ) \n\t\t)\n\n\t\tif ( originalLength === this[ pName ].length ) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tthis.notify({ [arrayPropName]: this[ arrayPropName as string ] })\n\t\treturn element\n\t}\n\n\tprivate _onChange: Observable<PropChangeEvent<EntropicComponent>> = new Observable<PropChangeEvent<EntropicComponent>>()\n}","import { Persistent, PersistentObject } from '../persistent/persistent'\nimport { ClassPropNames, PropPath, PropPathType } from '../types/utility-types'\nimport { DataSource, QueryOperator, QueryObject, QueryOrder, DocumentObject, QueryOperation } from './data-source'\n\n/**\n * Provides abstraction to the database access. You should gain access to a Model\n * object through the Store.getModel method instead of its constructor.\n */\nexport class Model<T extends Persistent>{\n\tstatic error = { \n\t\tpersistentNeedForSubCollection: 'The document parameter for a sub-collection should be a Persistent instace',\n\t\tinvalidQueryOrder: 'Cannot add where calls after or calls'\n\t}\n\n\tconstructor( stream: DataSource, persistentClass: Persistent | string, subCollection?: string ) {\n\t\tif ( subCollection ) {\n\t\t\tif( !( persistentClass instanceof Persistent ) ) throw new Error( Model.error.persistentNeedForSubCollection )\n\n\t\t\tthis.collectionName = `${ persistentClass.className }/${ persistentClass.id }/${ subCollection }`\n\t\t}\n\t\telse {\n\t\t\tthis.collectionName = persistentClass instanceof Persistent\n\t\t\t\t? persistentClass.className \n\t\t\t\t: persistentClass\n\t\t}\n\n\t\tthis._stream = stream\n\t}\n\n\t/**\n\t * Finds an stored object in the database by its id. The field id is provided\n\t * by the Persistent parent class and it is automatically managed. Therefore,\n\t * you should obtain the id by looking at the id field of the object.\n\t * \n\t * @param id the id to look for\n\t * @param instance you can pass an instace that will be filled with the found data\n\t * @returns a promise resolving to an instance with the found data\n\t */\n\tfindById<D extends T>( id: string, instance?: D ): Promise<D | undefined> {\n\t\treturn new Promise<D | undefined>( ( resolve, reject ) => {\n\t\t\tthis._stream.findById( id, this.collectionName )\n\t\t\t\t.then(( data: PersistentObject<D> ) => {\n\t\t\t\t\tif ( data ) {\n\n\t\t\t\t\t\tif ( !instance ) instance = Persistent.createInstance( data )\n\t\t\t\t\t\telse instance.fromObject( data ) \n\n\t\t\t\t\t\tresolve( instance )\n\t\t\t\t\t}\n\t\t\t\t\telse resolve( undefined )\n\t\t\t\t})\n\t\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\t\n\t/**\n\t * Stores an object in the database\n\t * \n\t * @param instance the object instance to store\n\t * @returns a promise \n\t */\n\tsave( instance: T ): Promise<void> {\n\t\tconst obj = instance.toObject() as PersistentObject<T> & { __rootCollections: DocumentObject }\n\t\t\n\t\tif ( this.collectionName !== obj.__className ) {\n\t\t\tobj.__rootCollections[ this.collectionName ] = obj.__rootCollections[ obj.__className ]\n\t\t\tdelete obj.__rootCollections[ obj.__className ]\n\t\t}\n\t\t\n\t\treturn new Promise<void>( ( resolve, reject ) => {\n\t\t\tthis._stream.save( obj.__rootCollections ) \n\t\t\t.then( () => resolve() )\n\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\t\n\t/**\n\t * Removes an element from the database by id\n\t * @param id the id of the element to be removed\n\t * @returns a promise\n\t */\n\tdelete( id: string ): Promise<void> {\n\t\treturn new Promise<void>( ( resolve, reject ) => {\n\t\t\tthis._stream.delete( id, this.collectionName ) \n\t\t\t.then( () => resolve() )\n\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\n\t/**\n\t * Call find to retrieve a Query object used to define the search conditions\n\t * @returns a Query object\n\t */\n\tfind<U extends T>(): Query<U> {\n\t\treturn new Query<U>( this as unknown as Model<U> )\n\t}\n\n\t/**\n\t * Define the search conditions. You pass query operations and how the query\n\t * results are returned to the QueryObject\n\t * @param queryObject the QueryObject with the search constrains\n\t * @param objectType Deprecated! - restricts the search to a specific instances of the class type\n\t * @returns a promise resolving to a collection of matched documents\n\t */\n\tquery<U extends T>( queryObject: QueryObject<U> = {}, /** @deprecated */ objectType?: U | string ): Promise<U[]> {\n\t\tif ( objectType ) {\n\t\t\tconst className = objectType instanceof Persistent ? objectType.className : objectType\n\t\t\tif ( !queryObject.operations ) queryObject.operations = []\n\t\t\tqueryObject.operations.push(\n\t\t\t\t{ property: '__className', operator: '==', value: className } as any \n\t\t\t)\n\t\t}\n\n\t\treturn this.mapToInstance( \n\t\t\t() => this._stream.find( this.preprocessQueryObject( queryObject ), this.collectionName ) \n\t\t)\n\t}\n\n\t/**\n\t * Get the amount of documents matching the query\n\t * @param queryObject the QueryObject with the search constrains\n\t * @returns a promise resolving to the amount of matched documents\n\t */\n\tcount( queryObject: QueryObject<T> ): Promise<number> {\n\t\treturn this._stream.count( queryObject as unknown as QueryObject<DocumentObject>, this.collectionName )\n\t}\n\n\t/**\n\t * Get the next bunch of documents matching the last query\n\t * @param limit the max amount of documents to retrieve. If not set, uses the\n\t * last limit set\n\t * @returns a promise resolving to a collection of matched documents\n\t */\n\tnext<U extends T>( limit?: number ): Promise<U[]> {\n\t\treturn this.mapToInstance( () => this._stream.next( limit ) )\n\t}\n\n\t// /**\n\t// * Get the previous bunch of documents matching the last query\n\t// * @param limit the max amount of documents to retrieve. If not set, uses the\n\t// * last limit set\n\t// * @returns a promise resolving to a collection of matched documents\n\t// */\n\t// prev<U extends T>( limit?: number ): Promise<U[]> {\n\t// \treturn this.mapToInstance( () => this._stream.prev( limit ) )\n\t// }\n\n\tprivate mapToInstance<U extends T>( from: ()=>Promise<DocumentObject[]> ): Promise<U[]> {\n\t\treturn new Promise<U[]>( ( resolve, reject ) => {\n\t\t\tfrom()\n\t\t\t\t.then( data => resolve( \n\t\t\t\t\tdata.map( obj => Persistent.createInstance( obj as any ))\n\t\t\t\t))\n\t\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\n\t/**\n\t * Normalizes the query object to match the data source requirements.\n\t * Call this method before you do any query operation on the concrete data source\n\t * @param queryObject the query object containing the query operations\n\t * @param operatorConversor a function that converts the query operators to the\n\t * operators supported by the concrete data source\n\t * @returns the normalized query object\n\t */\n\tprivate preprocessQueryObject<U>( queryObject: QueryObject<U> ): QueryObject<DocumentObject> {\n\t\tif ( Object.values( queryObject ).length === 0 ) return queryObject as unknown as QueryObject<DocumentObject>\n\n\t\tconst operations = queryObject.operations?.map( operation => {\n\t\t\tconst value = operation.value[0] ?? operation.value\n\n\t\t\tif ( DataSource.isArrayOperator( operation.operator ) && value instanceof Persistent ) {\n\t\t\t\treturn {\n\t\t\t\t\tproperty: Persistent.searchableArrayNameFor( operation.property as string ),\n\t\t\t\t\toperator: operation.operator,\n\t\t\t\t\tvalue: Array.isArray( operation.value )? operation.value.map( v => v.id ) : value.id,\n\t\t\t\t\taggregate: operation.aggregate\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn {\n\t\t\t\t\tproperty: operation.property,\n\t\t\t\t\toperator: operation.operator,\n\t\t\t\t\tvalue: operation.value instanceof Persistent ? { id: operation.value.id } : operation.value,\n\t\t\t\t\taggregate: operation.aggregate\n\t\t\t\t}\n\t\t\t}\n\t\t}) ?? []\n\n\t\treturn {\n\t\t\t...queryObject,\n\t\t\toperations\n\t\t} as QueryObject<DocumentObject>\n\t}\n\n\treadonly collectionName: string\n\tprivate _stream: DataSource\n}\n\n/**\n * The Query class is used to define the search conditions. You can chain\n * where operations to define the search conditions. The where operations\n * are stored in a QueryObject that is passed to the query method of the\n * Model class.\n */\nexport class Query<T extends Persistent> {\n\tconstructor( model: Model<T> ) {\n\t\tthis.model = model\t\n\t}\n\n\t/**\n\t * Matches all documents that the value of the property satisfies the condition\n\t * in the operator parameter. Subsequent `where` calls will be operated to the\n\t * previous ones using the AND operator\n\t * @param property the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @param aggregate if true, the query will use the logical or operator and \n\t * aggregate the results to the previous query\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.where( 'name', '==', 'John' )\n\t * query.where( 'age', '>', 18 )\n\t * query.where( 'age', '==', 18 ).where( 'name', '==', 'John' )\n\t * @see whereDeepProp\n\t * @see or\n\t * @see orDeepProp\n\t */\n\twhere<P extends ClassPropNames<T>>( property: P, operator: QueryOperator, value: Partial<T[P]> | Persistent, aggregate?: boolean ) {\n\t\tif ( this.queryObject.operations?.at(-1)?.aggregate && !aggregate ) throw new Error( Model.error.invalidQueryOrder )\n\n\t\tthis.queryObject.operations?.push({\n\t\t\tproperty,\n\t\t\toperator,\n\t\t\tvalue: value as any,\n\t\t\taggregate\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// where2<P extends PropPath<T>>( property: P, operator: QueryOperator, value: PropPathType<T, P> ) {\n\t// \tif ( property.indexOf( '.' ) > 0 ) return this.whereDeepProp( property, operator, value )\n\n\t// \tlet val = value instanceof Persistent? { id: value.id } : value\n\n\t// \tthis.queryObject.operations.push({\n\t// \t\tproperty,\n\t// \t\toperator,\n\t// \t\tvalue: val\n\t// \t})\n\n\t// \treturn this\n\t// }\n\n\t/**\n\t * Matches all documents that the value of the deep property satisfies the condition\n\t * in the operator parameter\n\t * @param propertyPath the path to the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.whereDeepProp( 'address.street', '==', 'Main Street' )\n\t * @see where\n\t * @see or\n\t * @see orDeepProp\n\t */\n\twhereDeepProp( propertyPath: PropPath<T>, operator: QueryOperator, value: PropPathType<T, typeof propertyPath>, aggregate?: boolean ) {\n\t\tif ( this.queryObject.operations?.at(-1)?.aggregate && !aggregate ) throw new Error( Model.error.invalidQueryOrder )\n\n\t\tconst props = ( propertyPath as string ).split( '.' )\n\t\tlet obj = {}\n\t\tlet result = props.length > 1? obj : value // TODO: review\n\n\t\tprops.slice(1).forEach(( prop, i ) => {\n\t\t\tobj[ prop ] = i < props.length - 2? {} : value \n\t\t\tobj = obj[ prop ]\n\t\t})\n\n\t\tthis.queryObject.operations?.push({\n\t\t\tproperty: props[0],\n\t\t\toperator,\n\t\t\tvalue: result,\n\t\t\taggregate\n\t\t} as QueryOperation<T>)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Matches all documents that the value of the property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param property the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.where( 'name', '==', 'John' ).and( 'age', '>', 18 )\n\t * @see andDeepProp\n\t * @see where\n\t * @see whereDeepProp\n\t * @see or\n\t * @see orDeepProp\n\t */\n\tand<P extends ClassPropNames<T>>( property: P, operator: QueryOperator, value: Partial<T[P]> | Persistent ) {\n\t\treturn this.where( property, operator, value )\n\t}\n\n\t/**\n\t * Matches all documents that the value of the deep property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param propertyPath the path to the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.whereDeepProp( 'address.street', '==', 'Main Street' ).andDeepProp( 'address.city', '==', 'New York' )\n\t * @see and\n\t * @see where\n\t * @see whereDeepProp\n\t * @see or\n\t * @see orDeepProp\n\t */\n\tandDeepProp( propertyPath: PropPath<T>, operator: QueryOperator, value: PropPathType<T, typeof propertyPath> ) {\n\t\treturn this.whereDeepProp( propertyPath, operator, value )\n\t}\n\n\t/**\n\t * Matches all documents that the value of the property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param property the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.or( 'name', '==', 'John' )\n\t * query.or( 'age', '>', 18 )\n\t * @see orDeepProp\n\t * @see where\n\t * @see whereDeepProp\n\t */ \n\tor<P extends ClassPropNames<T>>( property: P, operator: QueryOperator, value: Partial<T[P]> | Persistent ) {\n\t\treturn this.where( property, operator, value, true )\n\t}\n\n\t/**\n\t * Matches all documents that the value of the deep property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param propertyPath the path to the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.orDeepProp( 'address.street', '==', 'Main Street' )\n\t * @see or\n\t * @see where\n\t * @see whereDeepProp\n\t */\n\torDeepProp( propertyPath: PropPath<T>, operator: QueryOperator, value: PropPathType<T, typeof propertyPath> ) {\n\t\treturn this.whereDeepProp( propertyPath, operator, value, true )\n\t}\n\n\t/**\n\t * Defines a where condition to match documents that are instances of the\n\t * given class\n\t * @param classId the class name or an instance to match\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.instanceOf( 'Person' )\n\t * query.instanceOf( Person )\n\t * query.instanceOf( Person ).where( 'age', '>', 18 )\n\t */\n\tinstanceOf<U extends T>( classId: U | string ) {\n\t\tconst className = classId instanceof Persistent? classId.className : classId\n\t\tthis.queryObject.operations?.push({\n\t\t\tproperty: '__className' as any,\n\t\t\toperator: '==',\n\t\t\tvalue: className as any\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Executes the query and returns the result\n\t * @param limit the max amount of documents to retrieve. If not set, uses the\n\t * last limit set or all the matching documents\n\t * @returns a promise resolving to a collection of matched documents\n\t * @example\n\t * const namedJohn = await query.where( 'name', '==', 'John' ).get()\n\t */\n\tget<U extends T>( limit?: number ): Promise<U[]> {\n\t\tif ( limit ) {\n\t\t\tthis.queryObject.limit = limit\n\t\t}\n\t\treturn this.model.query( this.queryObject as unknown as QueryObject<U> )\n\t}\n\n\t/**\n\t * Limits the number of documents to retrieve\n\t * @param maxDocs the max amount of documents to retrieve\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.where( 'name', '==', 'John' ).limit( 10 )\n\t */\n\tlimit( maxDocs: number ) {\n\t\tthis.queryObject.limit = maxDocs\n\t\treturn this\n\t}\n\n\t/**\n\t * Orders the result set by a property.\n\t * @param propertyName The name of the property to order by\n\t * @param order The sort direction. Possible values are 'asc' and 'desc'\n\t * @returns a chainable query object\n\t * @example\n\t * query.orderBy( 'name', 'asc' )\n\t * query.orderBy( 'age', 'desc' )\n\t */\n\torderBy<P extends ClassPropNames<T>>( propertyName: P, order: QueryOrder = 'asc' ) {\n\t\tthis.queryObject.sort = { \n\t\t\tpropertyName, \n\t\t\torder \n\t\t}\n\t\t\n\t\treturn this\n\t}\n\n\t/**\n\t * Orders the result set by a deep property\n\t * \n\t * @param propertyPath The full path of the deep property. It should be \n\t * \t\t\t\t\t\t\t\t\t\t\tseparated by dots like person.name.firstName.\n\t * @param order The sort direction. Possible values are 'asc' and 'desc'\n\t * @returns a chainable query object\n\t */\n\torderByDeepProp( propertyPath: string, order: QueryOrder = 'asc' ) {\n\t\tthis.queryObject.sort = { \n\t\t\tpropertyName: propertyPath, \n\t\t\torder \n\t\t}\n\t\t\n\t\treturn this\n\t}\n\n\t/**\n\t * Returns the number of documents that match the query\n\t * @returns a promise resolving to the number of documents that match the query\n\t * @example\n\t * const count = await query.where( 'name', '==', 'John' ).count()\n\t */\n\tcount() {\n\t\treturn this.model.count( this.queryObject )\n\t}\n\n\tprivate queryObject: QueryObject<T> = { operations: [] } as QueryObject<T>\n\tprivate model: Model<T>\n}\n","import { DocumentReference, Persistent } from '../persistent/persistent';\nimport { DataSource } from './data-source';\nimport { Model } from './model';\n\n/**\n * The store is the main entry point for the data access layer.\n * It provides methods to retrieve models for collections and subcollections.\n * It also provides methods to populate property references with actual data from the store.\n * You need to register a data source before using the store.\n * @example\n * // Register a data source\n * Store.useDataSource( new FirestoreDataSource( firebase.firestore() ) )\n * // Retrieve a model for a collection\n * const model = Store.getModel( 'User' )\n * // Retrieve a model for a subcollection\n * const model = Store.getModelForSubCollection( user, 'Posts' )\n * // Populate property references\n * const user = await Store.populate( user )\n */\nexport class Store {\n\tprivate constructor(){}\n\n\tstatic error = { shouldBeRegistered: 'You should register a data source before using the data Store.' }\n\n\t/**\n\t * Registers a data source to be used by the store.\n\t * You need to register a data source before using the store.\n\t * @param dataSource the data source to be used by the store\n\t */\n\tstatic useDataSource( dataSource: DataSource ) {\n\t\tthis._dataSource = dataSource\n\t}\n\n\t/**\n\t * The data source currently used by the store\n\t * @returns the data source\n\t */\n\tstatic get dataSource() {\n\t\treturn Store._dataSource\n\t}\n\n\t/**\n\t * Retrieves a model for a collection\n\t * @param classId the class name or an instance of the document type stored in the collection\n\t * @returns the model for the collection\n\t */\n\tstatic getModel< T extends Persistent>( classId: T | string ): Model<T> {\n\t\tif ( !Store._dataSource ) throw new Error( this.error.shouldBeRegistered )\n\t\treturn new Model<T>( Store._dataSource, classId )\t\t\n\t}\n\n\t/**\n\t * Retrieves a model for a subcollection \n\t * @param document the persistent object that owns the subcollection\n\t * @param subCollection the name of the subcollection\n\t * @returns the model for the subcollection\n\t */\n\tstatic getModelForSubCollection< T extends Persistent>( document: Persistent, subCollection: string ): Model<T> {\n\t\tif ( !Store._dataSource ) throw new Error( this.error.shouldBeRegistered )\n\t\treturn new Model<T>( Store._dataSource, document, subCollection )\t\t\n\t}\n\n\t/**\n\t * Populates property references with actual data from the store.\n\t * It will not retrieve data if the instance is already populated\n\t * @param instance the data to be populated.\n\t * @returns the populated instance\n\t */\n\tstatic async populate<T extends Persistent | Persistent[]>( instance: T ): Promise<T> {\n\t\tif ( !instance ) return undefined as any\n\t\t\n\t\tconst populateItem = async ( item: Persistent ) => {\n\t\t\tconst ref: DocumentReference = item as any\n\t\t\tif ( !ref.__documentReference ) return item\n\t\t\tconst model = this.getModel( ref.__documentReference.storedInCollection )\n\n\t\t\tconst populated = await model.findById( ref.id, item ) \n\t\t\tif ( populated ) {\n\t\t\t\tpopulated['__documentReference' ] = undefined\n\t\t\t}\n\t\t\treturn populated\n\t\t}\n\t\t\n\t\tif ( Array.isArray( instance ) ) {\n\t\t\tconst items = await Promise.all(\n\t\t\t\tinstance.map( item => populateItem( item ) )\n\t\t\t)\n\t\t\treturn items.filter( item => item ) as T\n\t\t}\n\t\telse {\n\t\t\treturn populateItem( instance ) as Promise<T>\n\t\t}\n\t}\n\n\t/**\n\t * Checks if an instance is populated\n\t * @param instance the instance or array of instances to be checked\n\t * @returns true if the instance is populated\n\t */\n\tstatic isPopulated< T extends Persistent>( instance: T | readonly T[] ): boolean {\n\t\tif ( Array.isArray( instance ) ) {\n\t\t\treturn instance.reduce(\n\t\t\t\t( prevVal, item ) => prevVal && item['__documentReference'] === undefined,\n\t\t\t\ttrue \n\t\t\t)\n\t\t}\n\t\telse {\n\t\t\treturn instance['__documentReference'] === undefined\n\t\t}\n\t}\n\n\tprivate static _dataSource: DataSource\n}\n","import { Store } from './store'\nimport { Persistent, PersistentObject, Collections, PersistentProperty } from '../persistent/persistent'\nimport { ClassPropNames, Collection } from '../types/utility-types'\n\nexport type DocumentObject = PersistentObject<Persistent>\n\n/**\n * The query operators\n * @param == equal\n * @param != not equal\n * @param < less than\n * @param <= less than or equal\n * @param > greater than\n * @param >= greater than or equal\n * @param contains array contains\n * @param containsAny array contains any\n * @param in in\n * @param !in not in\n */\nexport type QueryOperator = '==' | '!=' | '<' | '<=' | '>' | '>=' | 'contains' | 'containsAny'// | 'in' | '!in'\n\n/**\n * A representation of a query operation\n * @param property the name of the property to be used in the query\n * @param operator the operator to be used in the query\n * @param value the value to be used in the query\n * @param aggregate if true, the query results will be aggregated using an `or` operator\n */\nexport type QueryOperation<T> = {\n\tproperty: ClassPropNames<T>\n\toperator: QueryOperator\n\tvalue: Partial<T[ClassPropNames<T>]> | {[key:string]: unknown}\n\taggregate?: boolean\n}\n\n/**\n * The sort order\n * @param asc ascending order\n * @param desc descending order\n */\nexport type QueryOrder = 'asc' | 'desc'\n\n/**\n * A representation of a full query\n * @param operations the query operations to be performed\n * @param limit the maximum number of items to be retrieved\n * @param sort sort info\n * @param sort.order the sort order\n * @param sort.propertyName the name of the property to be used for sorting\n */\nexport type QueryObject<T> = {\n\toperations?: QueryOperation<T>[]\n\tlimit?: number\n\tsort?: {\n\t\torder: QueryOrder\n\t\tpropertyName: ClassPropNames<T> | string\n\t}\n}\n\nexport type DocumentListenerUninstaller = () => void\n\ninterface DocumentChange {\n\tbefore: Persistent | undefined\n\tafter: Persistent,\n}\n\nexport type DocumentChangeListerner = ( change: DocumentChange ) => void\nexport interface DocumentChangeListernerHandler {\n\tuninstall: DocumentListenerUninstaller\n\tnativeHandler: unknown\n\tcollectionPath: string\n}\n\ntype CachedPropsUpdateCallback = ( doc: Persistent, prop: PersistentProperty )=>void\n\nexport interface CachedPropsUpdaterConfig {\n\tonUpdate?: CachedPropsUpdateCallback\n\tnoThrowOnNonImplementedListener?: boolean\n\tdocumentChangeListerner?: ( prop: PersistentProperty, listener: DocumentChangeListerner ) => DocumentChangeListernerHandler | undefined\n}\n\ninterface PropWithOwner { \n\tprop: PersistentProperty\n\tcollectionPropOwner: string \n}\n\n/**\n * The data source interface.\n * It defines the methods that must be implemented by a data source\n * A data source is able to retrieve and save data i.e: from a database, a file, a RestAPI, etc.\n * You can derive from this class to implement your own data source with the \n * A data source is used by the store to retrieve and save data.\n */\nexport abstract class DataSource {\n\tinstallCachedPropsUpdaters( config: CachedPropsUpdaterConfig = {} ): DocumentChangeListernerHandler[] {\n\t\tDataSource.onUpdate = config.onUpdate\n\t\tconst referencesWithStoredProps = Persistent.getSystemRegisteredReferencesWithCachedProps()\n\t\tconst collectionsToWatch: Collection<PropWithOwner[]> = {}\n\n\t\tObject.entries( referencesWithStoredProps ).forEach(([ className, props ]) => {\n\t\t\tprops.forEach( propInfo => {\n\t\t\t\tconst collectionName = Persistent.collectionPath( Persistent.createInstance( className ), propInfo )\n\t\t\t\tif ( !collectionsToWatch[ collectionName ] ) collectionsToWatch[ collectionName ] = []\n\t\t\t\tcollectionsToWatch[ collectionName ]!.push({\n\t\t\t\t\tprop: propInfo,\n\t\t\t\t\tcollectionPropOwner: className\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tconst handlers: DocumentChangeListernerHandler[] = []\n\t\tObject.entries( collectionsToWatch ).forEach(([ collectionNameToListen, props ]) => {\n\n\t\t\tconst listener = this.subscribeToDocumentChangeListerner( collectionNameToListen, e => DataSource.onDocumentChange( e, props ) )\n\n\t\t\tif ( !listener ) {\n\t\t\t\tif ( config.noThrowOnNonImplementedListener ) throw new Error( `The method documentChangeListerner has not been implemented in the concrete data source` )\n\t\t\t}\n\t\t\telse handlers.push( listener )\n\t\t})\n\n\n\t\t// \tprops.forEach( propInfo => {\n\t\t// \t\tif ( !propInfo.storeInCollection ) return\n\t\t\t\t\t\n\t\t// \t\tlet listenerHandler: DocumentChangeListernerHandler | undefined\n\t\t\t\t\n\t\t// \t\tif ( config.documentChangeListerner ) {\n\t\t// \t\t\tlistenerHandler = config.documentChangeListerner( propInfo, e => this.onDocumentChange( e, propInfo, className ) )\n\t\t// \t\t}\n\t\t// \t\telse {\n\t\t// \t\t\tlistenerHandler = this.subscribeToDocumentChangeListerner( propInfo, e => this.onDocumentChange( e, propInfo, className ) )\n\t\t// \t\t}\n\n\t\t// \t\tif ( !listenerHandler ) {\n\t\t// \t\t\tif ( config.noThrowOnNonImplementedListener ) throw new Error( `The method documentChangeListerner has not been implemented in the concrete data source` )\n\t\t// \t\t}\n\t\t// \t\telse handlers.push( listenerHandler )\n\t\t// \t})\n\t\t// })\n\n\t\treturn handlers\n\t}\n\n\t/**\n\t * Installs a document change listener\n\t * Implement the required logic to install a listener that will be called\n\t * when a document is changed in your concrete the data source\n\t * @param collectionPathToListen the name of the collection to be watched\n\t * @param props the properties to be watched in the collection\n\t * @param listener the listener to be called when a document is changed\n\t * @returns a function that uninstalls the listener. If the returned value is undefined\n\t * the method documentChangeListerner has not been implemented in the concrete data source\n\t */\n\tprotected subscribeToDocumentChangeListerner( collectionPathToListen: string, listener: DocumentChangeListerner ): DocumentChangeListernerHandler | undefined {\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Retrieves a document by id\n\t * Implement the required logic to retrieve a document by id from your concrete\n\t * the data source\n\t * @param id the id of the document to be retrieved\n\t * @param collectionName the name of the collection where the document is stored\n\t * @returns a promise resolving to the document object. The document object is \n\t * a plain object with the properties of the document class.\n\t */\n\tabstract findById( id: string, collectionName: string ): Promise< DocumentObject >\n\n\t/**\n\t * Retrieves all documents matching the query stored in the query object\n\t * Implement the required logic to retrieve the documents that match the \n\t * requirements in the query object from your concrete the data source\n\t * @param queryObject the query object containing the query operations\n\t * @param collectionName the name of the collection where the documents are stored\n\t * @returns a promise resolving to an array of document objects. The document object is\n\t * a plain object with the properties of the document class.\n\t * @see QueryObject\n\t * @see QueryOperation\n\t * @see QueryOperator\n\t * @see QueryOrder\n\t * @see DocumentObject\n\t */\n\tabstract find( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise< DocumentObject[] >\n\n\t/**\n\t * Saves a document\n\t * Implement the required logic to save the document in your concrete the data source\n\t * @param object A collection of documents to be saved\n\t * @returns a promise\n\t */\n\tabstract save( object: Collections ): Promise< void >\n\n\t/**\n\t * Deletes a document by id\n\t * Implement the required logic to delete a document by id from your concrete\n\t * data source\n\t * @param id the id of the document to be deleted\n\t * @param collectionName the name of the collection where the document is stored\n\t * @returns a promise\n\t */\n\tabstract delete( id: string, collectionName: string ): Promise<void>\n\n\t/**\n\t * Retrieves the next bunch of documents matching the query stored in the query object\n\t * Implement the required logic to retrieve the next bunch of documents that match the\n\t * requirements in the query object from your concrete the data source\n\t * @param limit the maximum number of items to be retrieved\n\t * @returns a promise resolving to an array representing the next bunch of document objects\n\t */\n\tabstract next( limit?: number ): Promise< DocumentObject[] >\n\n\t/**\n\t * Retrieves the number of documents matching the query stored in the query object\n\t * Implement the required logic to retrieve the number of documents that match the\n\t * requirements in the query object from your concrete the data source\n\t * @param queryObject the query object containing the query operations\n\t * @param collectionName the name of the collection where the documents are stored\n\t * @returns a promise resolving to the number of documents matching the query\n\t * @see QueryObject\n\t */\n\tabstract count( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise<number>\n\n\t/**\n\t * Utility method to convert a query object to a property path query object\n\t * \n\t * @param queryObject the query object to be converted\n\t * @returns a property path query object\n\t * @example\n\t * const queryObject = {\n\t * \toperations: [{ property: 'name', operator: '==', value: { ancestorName: { father: 'Felipe' }}]\n\t * }\n\t * const propPathQueryObject = DataSource.toPropertyPathQueryObject( queryObject )\n\t * // returned value: [{ property: 'name.ancestorName.father', operator: '==', value: 'Felipe' }]\n\t */\n\tstatic toPropertyPathOperations<T extends Persistent>( operations: QueryOperation<T>[] ): QueryOperation<T>[] {\n\t\tif ( !operations ) return []\n\n\t\treturn operations.map( operation => {\n\n\t\t\tif ( DataSource.isArrayOperator( operation.operator ) && operation.value[0] instanceof Persistent ) {\n\t\t\t\treturn {\n\t\t\t\t\tproperty: Persistent.searchableArrayNameFor( operation.property as string ),\n\t\t\t\t\toperator: operation.operator,\n\t\t\t\t\tvalue: ( operation.value as unknown as Persistent[] ).map( v => v.id ) as any,\n\t\t\t\t\taggregate: operation.aggregate\n\t\t\t\t} as QueryOperation<T>\n\t\t\t}\n\n\t\t\tconst [ path, value ] = this.toPropertyPathValue( operation.value )\n\t\t\tconst propPath = `${ String( operation.property ) }${ path? '.'+path : '' }` \n\n\t\t\treturn { \n\t\t\t\tproperty: propPath, \n\t\t\t\toperator:\toperation.operator,\n\t\t\t\tvalue,\n\t\t\t\taggregate: operation.aggregate\n\t\t\t} as QueryOperation<T>\n\t\t})\n\t}\n\n\tstatic isArrayOperator( operator: QueryOperator ): boolean {\n\t\treturn operator === 'containsAny' || operator === 'contains' //|| operator === 'in' || operator === '!in' \n\t}\n\n\tprivate static toPropertyPathValue( obj: {} ): [ string | undefined, unknown ] {\n\t\tif ( typeof obj === 'object' && !Array.isArray( obj ) ) {\n\t\t\tconst propName = Object.keys( obj )[0]!\n\t\t\tconst [ propPath, value ] = this.toPropertyPathValue( obj[ propName ] )\n\t\t\treturn [ `${ propName }${ propPath? '.'+propPath : '' }`, value ]\n\t\t}\n\t\telse {\n\t\t\treturn [ undefined, obj ]\n\t\t}\n\t}\n\n\tstatic async onDocumentChange( event: DocumentChange, propsToUpdate: PropWithOwner[] ) {\n\t\tif ( !event.before ) return\n\n\t\treturn propsToUpdate.map( async propWithOwner => {\n\n\t\t\tconst model = Store.getModel<any>( propWithOwner.collectionPropOwner )\n\t\t\tlet query = model.find()\n\n\t\t\tpropWithOwner.prop.cachedProps?.forEach( persistentPropName => {\n\t\t\t\tconst oldValue = event.before![ persistentPropName ]\n\t\t\t\tconst newValue = event.after[ persistentPropName ]\n\t\t\t\tif ( oldValue !== newValue ) {\n\t\t\t\t\tquery = query.orDeepProp( `${ propWithOwner.prop.name }.${ persistentPropName }`, '==', oldValue )\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst result = await query.get()\n\t\t\treturn Promise.all([\n\t\t\t\tresult.map( async document =>{\n\t\t\t\t\tpropWithOwner.prop.cachedProps?.forEach( async persistentPropName => {\n\t\t\t\t\t\tconst oldValue = event.before![ persistentPropName ]\n\t\t\t\t\t\tconst newValue = event.after[ persistentPropName ]\n\t\t\t\t\t\tif ( oldValue !== newValue ) {\n\t\t\t\t\t\t\tdocument[ `_${ propWithOwner.prop.name }` ][ `_${ persistentPropName }` ] = newValue\n\t\t\t\t\t\t\tawait model.save( document )\n\t\t\t\t\t\t\tthis.onUpdate?.( document, propWithOwner.prop )\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t])\n\t\t})\n\t}\n\n\tprivate static onUpdate: CachedPropsUpdateCallback | undefined\n}\n","import { Collections, Persistent, PersistentObject } from '../persistent/persistent'\nimport { Collection } from '../types/utility-types'\nimport { DataSource, DocumentChangeListerner, DocumentChangeListernerHandler, DocumentObject, QueryObject, QueryOperation } from \"./data-source\"\n\nexport interface JsonRawData {\n\t[ collection: string ]: {\n\t\t[ documentId: string ]: PersistentObject<Persistent>\n\t}\n}\n\nexport interface ErrorOnOperation {\n\tstore: string\n\tfind: string\n\tfindById: string\n\tdelete: string\n}\n\ntype QueryProcessors = {\n\t[ P in keyof Required<QueryObject<unknown>> ]: Function\n}\n\n/**\n * A concrete implementation of the DataSource interface uses an in-memory data store\n * initialized by a JSON object.\n * It is useful for testing purposes.\n * The data in the JSON object is not persisted.\n */\nexport class JsonDataSource extends DataSource {\n\n\t/**\n\t * @param jsonRawData the JSON object to be used as data store\n\t */\n\tconstructor( jsonRawData?: JsonRawData ) {\n\t\tsuper()\n\t\tif ( jsonRawData ) this._jsonRawData = jsonRawData;\n\t}\n\n\t/**\n\t * Set the JSON object to initialize the data store. Use to set the it after \n\t * the constructor has been called.\n\t * @param jsonRawData the JSON object to be used as data store\n\t */\n\tsetDataStore( rawDataStore: JsonRawData ) {\n\t\tthis._jsonRawData = rawDataStore;\n\t\treturn this\n\t}\n\n\t/**\n\t * Introduce a delay in the execution of operations to simulate a real data source\n\t * @param miliSeconds the number of milliseconds to delay the execution of operations\n\t * @returns a chainable reference to this object\n\t */\n\tsimulateDelay( miliSeconds: number ) {\n\t\tthis._simulateDelay = miliSeconds\n\t\treturn this\n\t}\n\n\tfindById( id: string, collectionName: string ): Promise< DocumentObject > {\n\t\tif ( this._simulateError?.findById ) throw new Error( this._simulateError.findById )\n\n\t\treturn this.resolveWithDelay( this._jsonRawData[ collectionName ]?.[ id ] )\n\t}\n\n\tsave( collections: Collections ): Promise< void > {\n\t\tif ( this._simulateError?.store ) throw new Error( this._simulateError.store )\n\n\t\tObject.entries( collections ).forEach(([ collectionName, collection ]) => {\n\t\t\tif ( !this._jsonRawData[ collectionName ] ) this._jsonRawData[ collectionName ] = {}\n\t\t\tcollection?.forEach( document => {\n\t\t\t\tconst oldValue = this._jsonRawData[ collectionName ]![ document.id ]\n\t\t\t\tthis._jsonRawData[ collectionName ]![ document.id ] = document\n\t\t\t\tif ( oldValue )\t{\n\t\t\t\t\tthis.notifyChange( collectionName, Persistent.createInstance( document ), Persistent.createInstance( oldValue ))\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\t\treturn this.resolveWithDelay()\n\t}\n\n\tfind( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise< DocumentObject[] > {\n\t\tif ( this._simulateError?.find ) throw new Error( this._simulateError.find )\n\n\t\tconst rawDataArray = Object.values( this._jsonRawData[ collectionName ] || {} )\n\t\tif ( !queryObject ) return this.resolveWithDelay( rawDataArray )\n\t\t\n\t\tthis._lastLimit = queryObject.limit || 0\n\t\tthis._cursor = 0\n\n\t\tthis._lastMatchingDocs = Object.entries( queryObject ).reduce(\n\t\t\t( prevDocs, [ processMethod, value ]) => {\n\n\t\t\t\treturn this.queryProcessor( prevDocs, processMethod as any, value )\n\n\t\t\t}, Object.values( rawDataArray )\n\t\t)\n\n\t\treturn this.resolveWithDelay( this._lastMatchingDocs.slice( 0, queryObject.limit ) )\n\t}\n\n\tdelete( id: string, collectionName: string ): Promise<void> {\n\t\tif ( this._simulateError?.delete ) throw new Error( this._simulateError.delete )\n\n\t\tdelete this._jsonRawData[ collectionName ]![ id ]\n\t\treturn this.resolveWithDelay()\n\t}\n\n\tnext( limit?: number ): Promise< DocumentObject[] > {\n\t\tif ( limit ) this._lastLimit = limit\n\t\tthis.incCursor( this._lastLimit )\n\n\t\treturn this.resolveWithDelay( this._lastMatchingDocs.slice( this._cursor, this._cursor + this._lastLimit ) )\n\t}\n\n\tcount( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise<number> {\n\t\treturn this.resolveWithDelay(\n\t\t\tObject.keys( this._jsonRawData[ collectionName ] ?? {} ).length\n\t\t)\n\t}\n\n\t/**\n\t * @returns the raw data store data as a JSON object\n\t */\n\tget rawData() {\n\t\treturn this._jsonRawData\n\t}\n\n\t/**\n\t * Wait for all pending promises to be resolved\n\t * @returns a promise that resolves when all pending promises are resolved\n\t */\n\twait() {\n\t\treturn Promise.all([ ...this._pendingPromises ])\n\t}\n\n\tprivate incCursor( amount: number ) {\n\t\tthis._cursor += amount \n\t\tif ( this._cursor > this._lastMatchingDocs.length ) {\n\t\t\tthis._cursor = this._lastMatchingDocs.length\n\t\t}\n\t}\n\n\tsimulateError( error: string | ErrorOnOperation | undefined ): this {\n\t\tif ( error === undefined ) {\n\t\t\tthis._simulateError = undefined\n\t\t\treturn this\n\t\t}\n\n\t\tif ( typeof error === 'string' ) {\n\t\t\tthis._simulateError = {\n\t\t\t\tstore: error,\n\t\t\t\tfind: error,\n\t\t\t\tfindById: error,\n\t\t\t\tdelete: error\n\t\t\t}\n\t\t}\n\t\telse this._simulateError = error\n\n\t\treturn this\n\t}\n\n\tprotected override subscribeToDocumentChangeListerner( collectionNameToListen: string, listener: DocumentChangeListerner ): DocumentChangeListernerHandler | undefined {\n\t\tdelete this._listener[ collectionNameToListen ]\n\t\tthis._listener[ collectionNameToListen ] = listener\n\t\treturn {\n\t\t\tuninstall: ()=> delete this._listener[ collectionNameToListen ],\n\t\t\tnativeHandler: listener,\n\t\t\tcollectionPath: collectionNameToListen,\n\t\t}\n\t}\n\n\tprivate notifyChange( collectionPath: string, document: Persistent, oldValue: Persistent | undefined ) {\n\t\tconst listener = this._listener[ collectionPath ]\n\t\tif ( listener ) {\n\t\t\tconst event = {\n\t\t\t\tbefore: oldValue,\n\t\t\t\tafter: document,\n\t\t\t\tcollectionPath\n\t\t\t}\n\t\t\tlistener( event )\n\t\t}\n\t}\n\n\tprivate decCursor( amount: number ) {\n\t\tthis._cursor -= amount \n\t\tif ( this._cursor < 0 ) {\n\t\t\tthis._cursor = 0\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tprivate queryProcessor<T, P extends keyof QueryProcessors>( docs: DocumentObject[], processMethod: P, value: QueryObject<T>[P] ) {\n\n\t\tconst processors: QueryProcessors = {\n\n\t\t\tlimit: ( limit: number ) => docs, //.slice( 0, limit ),\n\n\t\t\toperations: ( operations: QueryOperation<T>[] ) => this.retrieveQueryDocs( docs, operations ),\n\n\t\t\tsort: ({ order, propertyName }) => docs.sort( ( a, b ) => {\n\t\t\t\tif ( order === 'asc' ) {\n\t\t\t\t\treturn this.deepValue( a, propertyName ) > this.deepValue( b, propertyName )? 1 : -1 \n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn this.deepValue( a, propertyName ) < this.deepValue( b, propertyName )? 1 : -1\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\treturn processors[ processMethod ]( value )\n\t}\n\n\tprivate retrieveQueryDocs<T>( docs: DocumentObject[], queryOperations: QueryOperation<T>[] ): DocumentObject[] {\n\t\treturn queryOperations.reduce(( prevDocs, queryOperation, i ) => {\n\t\t\tif ( queryOperation.aggregate ) {\n\t\t\t\tconst aggregate = docs.filter( doc => this.isQueryMatched( doc, queryOperation ) )\n\t\t\t\tif ( i === 0 ) return aggregate\n\t\t\t\telse return prevDocs.concat( aggregate )\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn prevDocs.filter( doc => this.isQueryMatched( doc, queryOperation ) )\n\t\t\t}\n\t\t}, docs )\n\t}\n\n\tprivate deepValue( obj: {}, propertyPath: string /*like person.name.firstName*/) {\n\t\tconst propChain = propertyPath.split( '.' )\n\t\treturn propChain.reduce(( value, prop ) => value[ prop ], obj )\n\t}\n\n\tprivate isQueryMatched<T>( doc: DocumentObject, queryOperation: QueryOperation<T> ) {\n\t\tconst queryOperator = {\n\t\t\t'==': <U>(a: U, b: U) => a === b,\n\t\t\t'!=': <U>(a: U, b: U) => a !== b,\n\t\t\t'<': <U>(a: U, b: U) => a < b,\n\t\t\t'<=': <U>(a: U, b: U) => a <= b,\n\t\t\t'>': <U>(a: U, b: U) => a > b,\n\t\t\t'>=': <U>(a: U, b: U) => a >= b,\n\t\t\t'containsAny': <U>(a: U[], b: U[]) => a?.some( v => b?.includes( v ) ),\n\t\t\t'contains': <U>(a: U[], b: U) => a?.includes( b ),\n\t\t}\n\n\t\tconst { property, value, operator } = queryOperation\n\t\tconst [ propValue, v ] = this.retrieveValuesToCompare( doc, property as string, value )\n\n\t\treturn queryOperator[ operator ]( propValue, v )\n\t}\n\n\tprivate retrieveValuesToCompare( doc: DocumentObject, propertyName: string, value: unknown ): [ any, any ] {\n\t\tconst propertyValue = doc[ propertyName ]\n\n\t\tif ( propertyValue && typeof value === 'object' && !Array.isArray( value )) {\n\t\t\tconst propName = Object.keys( value! )[0]!\n\t\t\tvar [ propVal, val ] = this.retrieveValuesToCompare( propertyValue, propName, value?.[ propName ] )\n\t\t}\n\n\t\treturn [ propVal || propertyValue, val || value ]\n\t}\n\n\tprivate resolveWithDelay<T>( data?: T ): Promise<T> {\n\t\tif ( this._simulateDelay <=0 ) return Promise.resolve( data! )\n\n\t\tconst promise = new Promise<T>( resolve => {\n\t\t\tsetTimeout(\n\t\t\t\t()=> resolve( data! ),\n\t\t\t\tthis._simulateDelay\n\t\t\t)\n\t\t})\n\t\tthis._pendingPromises.push( promise )\n\t\tpromise.finally(\n\t\t\t()=> this._pendingPromises = this._pendingPromises.filter( p => p === promise )\n\t\t)\n\t\treturn promise\n\t}\n\n\tprivate _jsonRawData: JsonRawData = {}\n\tprivate _lastMatchingDocs: DocumentObject[] = []\n\tprivate _lastLimit: number = 0\n\tprivate _cursor: number = 0\n\tprivate _simulateDelay: number = 0\n\tprivate _pendingPromises: Promise<any>[] = []\n\tprivate _simulateError: ErrorOnOperation | undefined\n\tprivate _listener: Collection<DocumentChangeListerner> = {}\n}\n","export type UploadProgress = ( uploadedBytes: number, fileSize: number ) => void\n\ntype CloudStorageFactory = ()=>CloudStorage\n\ninterface CloudStorageFactoryMap { \n\t[ cloudStorageProviderName: string ] : CloudStorageFactory \n}\n\nexport interface UploadControl {\n\tpause: ()=>void\n\tresume: ()=>void\n\tcancel: ()=>void\n\tonProgress: ( callback: UploadProgress )=>void\n}\n\nexport type StorableData = File | Blob | Uint8Array | ArrayBuffer\n\nexport abstract class CloudStorage {\n\tabstract save( id: string, data: StorableData, progress?: UploadProgress ): Promise<string>\n\tabstract getUrl( reference: string ): Promise<string>\n\tabstract uploadControl(): UploadControl\n\tabstract delete( reference: string ): Promise<void>\n\n\tstatic registerCloudStorage( cloudStorageProviderName: string, factory: CloudStorageFactory ) {\n\t\tCloudStorage._cloudStorageFactoryMap[ cloudStorageProviderName ] = factory\n\t}\n\n\tstatic createInstance( providerName: string ) {\n\t\tconst provider = CloudStorage._cloudStorageFactoryMap[ providerName ]\n\t\tif ( !provider ) {\n\t\t\tthrow new Error( `You should register the ${ providerName } cloud storage provider prior to use it`)\n\t\t}\n\n\t\treturn provider()\n\t}\n\n\tget className(): string {\n\t\treturn this[ '__className' ];\n\t}\n\n\tstatic useCloudStorage( provider: CloudStorage ) {\n\t\tCloudStorage._defaultCloudStorage = provider\n\t}\n\n\tstatic get defaultCloudStorage() {\n\t\tif ( !CloudStorage._defaultCloudStorage ) {\n\t\t\tthrow new Error( 'You should define a default cloud storage provider prior to use it')\n\t\t}\n\t\treturn CloudStorage._defaultCloudStorage\n\t}\n\tstatic _defaultCloudStorage: CloudStorage\n\tprivate static _cloudStorageFactoryMap: CloudStorageFactoryMap = {}\n}\n\nexport function registerCloudStorage( cloudStorageProviderName: string, factory: CloudStorageFactory ) {\n\tCloudStorage.registerCloudStorage( cloudStorageProviderName, factory )\n\treturn ( constructor: Function ) => {\n\t\tconstructor.prototype.__className = cloudStorageProviderName\n\t}\n}\n","import { CloudStorage, registerCloudStorage, StorableData, UploadControl, UploadProgress } from './cloud-storage'\n\n@registerCloudStorage( 'MockCloudStorage', ()=>new MockCloudStorage() )\nexport class MockCloudStorage extends CloudStorage {\n\tconstructor( pathToMockFiles: string = '' ) {\n\t\tsuper()\n\t\tthis._pathToMockFiles = pathToMockFiles\n\t}\n\n\t/**\n\t * Introduce a delay in the execution of operations to simulate a real data source\n\t * @param miliSeconds the number of milliseconds to delay the execution of operations\n\t * @returns a chainable reference to this object\n\t */\n\tsimulateDelay( miliSeconds: number ) {\n\t\tthis._simulateDelay = miliSeconds\n\t\treturn this\n\t}\n\n\tprivate resolveWithDelay<T>( data?: T ): Promise<T> {\n\t\tif ( this._simulateDelay <= 0 ) return Promise.resolve( data! )\n\n\t\tconst promise = new Promise<T>( resolve => {\n\t\t\tsetTimeout(\n\t\t\t\t()=> resolve( data! ),\n\t\t\t\tthis._simulateDelay\n\t\t\t)\n\t\t})\n\t\tthis._pendingPromises.push( promise )\n\t\tpromise.finally(\n\t\t\t()=> this._pendingPromises = this._pendingPromises.filter( p => p === promise )\n\t\t)\n\t\treturn promise\n\t}\n\n\tsave( id: string, data: StorableData ): Promise<string> {\n\t\tconst fullPath = id\n\n\t\tif ( this._onProgress ) this._onProgress( 0, 100 )\n\n\t\tthis.mockFileSystem[ id ] = JSON.stringify( data ) \n\n\t\tif ( this._onProgress ) this._onProgress( 100, 100 )\n\n\t\tconst ref = data instanceof File? data.name : fullPath\n\t\treturn this.resolveWithDelay( ref )\n\t}\n\n\tuploadControl(): UploadControl {\n\t\treturn {\n\t\t\tresume: ()=>{},\n\t\t\tpause: ()=>{},\n\t\t\tcancel: ()=>{},\n\t\t\tonProgress: callback => this._onProgress = callback\n\t\t}\n\t}\n\n\tgetUrl( reference: string ): Promise<string> {\n\t\treturn Promise.resolve( this._pathToMockFiles + reference )\n\t}\n\n\tdelete( reference: string ) {\n\t\tdelete this.mockFileSystem[ reference ]\n\t\treturn this.resolveWithDelay<void>()\n\t}\n\n\tprivate _simulateDelay: number = 0\n\tprivate _pendingPromises: Promise<any>[] = []\n\tprivate _onProgress: UploadProgress | undefined\n\tprivate _pathToMockFiles: string\n\tpublic mockFileSystem = {}\n}","import { Callback, Observable } from '../observable/observable'\nimport { persistent, Persistent, registerPersistentClass } from '../persistent/persistent'\nimport { CloudStorage, StorableData, UploadControl, UploadProgress } from './cloud-storage'\n\nexport enum StoredFileEvent { stored, pendingDataSet, deleted }\nexport interface StoredFileChange {\n\tevent: StoredFileEvent\n\tpendingData?: StorableData\n\tstoredFile: StoredFile\n}\n\nexport interface StoreParams {\n\tdata?: StorableData, \n\tfileName?: string, \n\tprogress?: UploadProgress, \n\tcloudStorageProvider?: CloudStorage \n}\n\n@registerPersistentClass( 'StoredFile' )\nexport class StoredFile extends Persistent{\n\n\tasync save({ data, fileName, progress, cloudStorageProvider }: StoreParams = {}): Promise<void> {\n\t\tconst dataToStore = data || this._pendingData\n\t\tif ( !dataToStore ) return\n\t\tif ( this._reference ) await this.delete()\n\n\t\tthis.provider = cloudStorageProvider || CloudStorage.defaultCloudStorage\n\t\tthis._originalFileName = fileName || ( dataToStore instanceof File? dataToStore.name : undefined )\n\n\t\tthis._reference = await this.provider.save( this.id, dataToStore, progress )\n\t\tthis._url = await this.provider.getUrl( this._reference )\n\n\t\tthis._pendingData = undefined\n\t\tthis._onChange.notify({ event: StoredFileEvent.stored, storedFile: this })\n\t}\n\n\tuploadControl(): UploadControl {\n\t\treturn this.provider.uploadControl()\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tif ( !this._reference ) throw new Error( 'Cannot delete a not stored file' )\n\t\tawait this.provider.delete( this._reference )\n\t\tthis._reference = undefined\n\t\tthis._url = undefined\n\t\tthis._onChange.notify({ event: StoredFileEvent.deleted, storedFile: this })\n\t}\n\n\tset provider( value: CloudStorage ) {\n\t\tthis._provider = value\n\t\tthis._cloudStorageProviderName = value.className\n\t}\n\n\tget provider() {\n\t\tif ( !this._provider ) {\n\t\t\ttry {\n\t\t\t\tthis._provider = CloudStorage.createInstance( this._cloudStorageProviderName! )\n\t\t\t} \n\t\t\tcatch {\n\t\t\t\tthis._provider = CloudStorage.defaultCloudStorage\n\t\t\t}\n \t\t}\n\t\treturn this._provider\n\t}\n\n\tget url() {\n\t\treturn this._url\n\t}\n\n\tget mimeType() {\n\t\treturn this._mimeType\n\t}\n\n\tsetDataToStore( data: StorableData ) {\n\t\tthis._pendingData = data\n\t\tthis._originalFileName = data instanceof File? data.name : undefined\n\t\tthis._mimeType = data instanceof Blob? data.type : undefined\n\t\tthis._onChange.notify({ \n\t\t\tevent: StoredFileEvent.pendingDataSet, \n\t\t\tpendingData: data,\n\t\t\tstoredFile: this \n\t\t})\n\t\treturn this\n\t}\n\n\tget originalFileName() {\n\t\treturn this._originalFileName\n\t}\n\n\tonChange( listenerCallback: Callback<StoredFileChange> ) {\n\t\treturn this._onChange.subscribe( listenerCallback )\n\t}\n\n\t@persistent private _reference: string | undefined\n\t@persistent private _url: string | undefined\n\t@persistent private _cloudStorageProviderName: string | undefined\n\t@persistent private _originalFileName: string | undefined\n\t@persistent private _mimeType: string | undefined\n\tprivate _provider: CloudStorage | undefined\n\tprivate _pendingData: StorableData | undefined\n\tprivate _onChange: Observable<StoredFileChange> = new Observable<StoredFileChange>()\n}\n","import { Observable } from '../observable/observable'\nimport { AuthProvider, SignData, UserCredentials } from \"./user-auth-types\"\n\n/**\n * The AuthService class is an abstract class that defines the interface of an authentication service.\n * You should derive from this class to implement your own authentication service.\n */\nexport abstract class AuthService {\n\tabstract signUp<T extends {}>( signData: SignData ): Promise<UserCredentials<T>>\n\tabstract login<T extends {}>( signData: SignData ): Promise<UserCredentials<T>>\n\tabstract logout(): Promise<void>\n\tabstract resetEmailPassword( email: string ): Promise<void>\n\tabstract refreshToken(): Promise<void>\n\tabstract linkAdditionalProvider( provider: AuthProvider ): Promise<unknown>\n\tabstract unlinkProvider( provider: AuthProvider ): Promise<unknown>\n\tabstract onAuthStateChange<T extends {}>( onChange: (userCredentials: UserCredentials<T> | undefined) => void ): void\n\tabstract resendVerificationEmail( email: string, password: string, verificationLink: string ): Promise<void>\n}\n\nexport type AuthErrorCode = 'wrongPassword' | 'popupClosedByUser' | 'userNotFound' | 'invalidEmail' | 'missingPassword' | 'missingEmail'\n\nexport interface AuthError {\n\tcode: AuthErrorCode\n\tmessage: string\n}\n\n/**\n * Types the callback to accept a user credentials object\n */\nexport type ResovedCallback<T extends {}> = ( credentials: UserCredentials<T> ) => void\nexport type RejectedCallback = ( reason: AuthError ) => void\n\n/**\n * The Auth class is a singleton that provides a unified interface to the authentication service.\n * You should register an authentication service by using `Auth.useAuthService` \n * method before using the Auth class.\n */\nexport class Auth extends AuthService {\n\tstatic error = { shouldBeRegistered: 'You should register an auth service before using Auth.' }\n\n\tprotected constructor() {\n\t\tsuper()\n\t\tif (!Auth._authService ) throw ( new Error( Auth.error.shouldBeRegistered ) )\n\t\tAuth._authService.onAuthStateChange( \n\t\t\tuserCredentials => this.authStateChanged( userCredentials ) \n\t\t)\n\t}\n\n\t/**\n\t * Registers an authentication service to be used by the Auth class.\n\t * You need to register an authentication service before using the Auth class.\n\t * @param authService the authentication service to be used by the Auth class\n\t */\n\tstatic useAuthService( authService: AuthService ) {\n\t\tif ( Auth._authService != authService ) {\n\t\t\tAuth._authService = authService\n\t\t\tthis._instance = undefined\n\t\t}\n\t}\n\n\t/**\n\t * The instance of the Auth class\n\t * @returns the authentication service\n\t */\n\tstatic get instance() {\n\t\treturn this._instance || (this._instance = new this() )\n\t}\n\n\t/**\n\t * Signs up a new user\n\t * @param singData the data to be used to sign up the user\n\t * @returns a promise that resolves to the user credentials\n\t * @example\n\t * // Sign up a new user with email and password\n\t * Auth.instance.signUp({ authProvider: 'email', email: 'john@test.com', password: '123456' })\n\t * // Sign up a new user with a Google account\n\t * Auth.instance.signUp({ authProvider: 'google'})\n\t */\n\tsignUp<T extends {}>( singData: SignData ): Promise<UserCredentials<T>> {\n\t\treturn Auth._authService.signUp( singData )\n\t}\n\n\t/**\n\t * Logs in an existing user\n\t * @param singData the data to be used to log in the user\n\t * @returns a promise that resolves to the user credentials\n\t * @example\n\t * // Log in an existing user with email and password\n\t * Auth.instance.login({ authProvider: 'email', email: 'john@test.com', password: '123456' })\n\t * // Log in an existing user with a Google account\n\t * Auth.instance.login({ authProvider: 'google'})\n\t */\n\tlogin<T extends {}>( singData: SignData ): Promise<UserCredentials<T>> {\n\t\treturn Auth._authService.login( singData )\n\t}\n\t\n\t/**\n\t * Logs out the current user\n\t * @returns a promise that resolves when the user is logged out\n\t */\n\tlogout(): Promise<void> {\n\t\treturn Auth._authService.logout()\n\t}\n\n\t/**\n\t * Resets the password associated with the email.\n\t * @param email the email address of the user to reset the password\n\t * @returns a promise that resolves when the process is done\n\t */\n\tresetEmailPassword( email: string ) {\n\t\treturn Auth._authService.resetEmailPassword( email )\n\t}\n\n\t/**\n\t * Resends the email verification to the user.\n\t * @returns a promise that resolves when the process is done\n\t */\n\toverride resendVerificationEmail( email: string, password: string, verificationLink: string ): Promise<void> {\n\t\treturn Auth._authService.resendVerificationEmail( email, password, verificationLink )\n\t}\n\n\toverride refreshToken(): Promise<void> {\n\t\treturn Auth._authService.refreshToken()\n\t}\n\n\t/**\n\t * Adds a listener to be called when the authentication state changes.\n\t * @param onChange the listener to be called when the authentication state changes.\n\t * The listener is called with the user credentials as a parameter.\n\t * If the user is logged out, the listener is called with `undefined` as a parameter.\n\t * @returns a function to remove the listener\n\t * @example\n\t * // Add a listener to be called when the authentication state changes\n\t * const removeListener = Auth.instance.onAuthStateChange( userCredentials => {\n\t * \tif ( userCredentials ) {\n\t * \t\t// The user is logged in\n\t * \t} else {\n\t * \t\t// The user is logged out\n\t * \t}\n\t * })\n\t */\n\tonAuthStateChange<T extends {}>( onChange: ( userCredentials: UserCredentials<T> )=>void ) {\n\t\treturn this._onAuthStateChange.subscribe( onChange )\n\t}\n\n\t/**\n\t * Removes a listener that was added by `onAuthStateChange` method.\n\t * @param onChange the listener to be removed\n\t */\n\tremoveAuthStateChange<T extends {}>( onChange: ( userCredentials: UserCredentials<T> )=>void ) {\n\t\tthis._onAuthStateChange.unsubscribe( onChange )\n\t}\n\n\t/**\n\t * Links an additional authentication provider to the authenticated user.\n\t * @param provider the provider to be linked\n\t * @returns a promise that resolves when the process is done\n\t * @example\n\t * // Link a Google account to the auth service\n\t * Auth.instance.linkAdditionalProvider({ authProvider: 'google' })\n\t */\n\tlinkAdditionalProvider( provider: AuthProvider ): Promise<unknown> {\n\t\treturn Auth._authService.linkAdditionalProvider( provider )\n\t}\n\n\t/**\n\t * Unlinks an authentication provider from the authenticated user.\n\t * @param provider the provider to be unlinked\n\t * @returns a promise that resolves when the process is done\n\t * @example\n\t * // Unlink the Google account from the auth service\n\t * Auth.instance.unlinkProvider({ authProvider: 'google' })\n\t */\n\tunlinkProvider( provider: AuthProvider ): Promise<unknown> {\n\t\treturn Auth._authService.unlinkProvider( provider )\n\t}\n\n\tprivate authStateChanged( userCredentials: UserCredentials<{}> | undefined ) {\n\t\tthis._onAuthStateChange.notify( userCredentials )\n\t}\n\n\tprivate static _instance: Auth | undefined = undefined\n\tprivate static _authService: AuthService\n\tprivate _onAuthStateChange: Observable<UserCredentials<{}>> = new Observable<UserCredentials<{}>>()\n}","import { Collection } from '../types/utility-types'\nimport { AuthService, RejectedCallback, ResovedCallback } from \"./auth\"\nimport { UserCredentials, SignData, AuthProvider } from \"./user-auth-types\"\n\nexport class AuthMock extends AuthService {\n\n\tsignUp<T extends {}>( signData: SignData ): Promise<UserCredentials<T>> {\n\t\tconst { verificationLink, email, password, authProvider } = signData\n\t\n\t\tconst promise = new Promise<UserCredentials<T>>( async ( resolve: ResovedCallback<T>, reject: RejectedCallback ) => {\n\t\t\tif ( authProvider === 'email' ) {\n\t\t\t\tif ( !email ) reject({ code: 'missingEmail', message: 'missingEmail' })\n\t\t\t\tif ( !password ) reject({ code: 'missingPassword', message: 'missingPassword' })\n\t\t\t}\n\t\t\tif ( password !== 'fail' && email !== 'fail' ) {\n\t\t\t\tthis._loggedUser = this.userCredentials<T>( signData )\n\t\t\t\tthis._fakeRegisteredUsers[ this._loggedUser.id ] = this._loggedUser \n\t\t\t\tresolve( this._loggedUser as UserCredentials<T> )\n\t\t\t\tthis.notifyChange?.( this._loggedUser )\n\t\t\t} \n\t\t\telse {\n\t\t\t\treject({ code: 'userNotFound', message: verificationLink || 'Test auth error' })\n\t\t\t\tthis.notifyChange?.( undefined )\n\t\t\t}\n\t\t})\n\t\tthis.pendingPromises.push( promise )\n\t\treturn promise\n\t}\n\n\tlogin<T extends {}>( signData: SignData ): Promise<UserCredentials<T>> {\n\t\tconst fakeUser = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === signData.email \n\t\t)\n\n\t\tif ( signData.authProvider === 'email' && !fakeUser && signData.email) {\n\t\t\tsignData.email = 'fail'\n\t\t}\n\n\t\treturn this.signUp( signData )\n\t}\n\n\tonAuthStateChange<T extends {}>( onChange: ( userCredentials: UserCredentials<T> )=>void ) {\n\t\tthis.notifyChange = onChange\n\t\tthis.notifyChange( this._loggedUser )\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tconst promise = new Promise<void>( resolve => {\n\t\t\tthis._loggedUser = undefined\n\t\t\tresolve() \n\t\t\tthis.notifyChange?.( undefined )\n\t\t})\n\t\tthis.pendingPromises.push( promise )\n\t\treturn promise\n\t}\n\n\tresetEmailPassword( email: string ) {\n\t\tconst fakeUserExists = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === email \n\t\t)\n\n\t\tif ( fakeUserExists ) return Promise.resolve()\n\t\telse return Promise.reject({ code: 'userNotFound', message: 'Test auth error' })\n\t}\n\n\tresendVerificationEmail( email: string, _password: string, _verificationLink: string ) {\n\t\tconst fakeUserExists = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === email \n\t\t)\n\n\t\tif ( fakeUserExists ) return Promise.resolve()\n\t\telse return Promise.reject({ code: 'userNotFound', message: 'Test auth error' })\n\t}\n\n\toverride refreshToken(): Promise<void> {\n\t\treturn Promise.resolve()\n\t}\n\n\tlinkAdditionalProvider( provider: AuthProvider ): Promise<unknown> {\n\t\tthrow new Error('Not implemented.')\n\t}\n\t\n\tunlinkProvider( provider: AuthProvider ): Promise<unknown> {\n\t\tthrow new Error('Not implemented.')\n\t}\n\t\n\tasync flush() {\n\t\tawait Promise.all(this.pendingPromises)\n this.pendingPromises = []\n\t}\n\n\tfakeRegisteredUser<T extends {}>( userCredentials: UserCredentials<T> ) {\n\t\tif ( this._fakeRegisteredUsers[ userCredentials.id ] ) throw new Error( `User with id ${ userCredentials.id } already exists in fake user list`)\n\t\tthis._fakeRegisteredUsers[ userCredentials.id ] = userCredentials\n\t\treturn this\n\t}\n\n\tget fakeRegisteredUsers() {\n\t\treturn this._fakeRegisteredUsers\n\t}\n\n\tprivate userCredentials<T extends {}>( signData: SignData ): UserCredentials<T> {\n\t\tconst fakeUser = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === signData.email \n\t\t)\n\t\t\n\t\tif ( fakeUser ) {\n\t\t\treturn { ...fakeUser as UserCredentials<T> }\n\t\t}\n\t\telse {\n\t\t\treturn ({\n\t\t\t\tid: signData.authProvider || `testUID${ signData.email? '-' + signData.email : '' }`,\n\t\t\t\temail: signData.email || 'testEmail',\n\t\t\t\tname: signData.authProvider || `testName${ signData.email? ' ' + signData.email : '' }` ,\n\t\t\t\tphoneNumber: 'testPhone',\n\t\t\t\tcustomData: {\n\t\t\t\t\trole: 'test'\n\t\t\t\t} as unknown as T,\n\t\t\t\tlastLogin: 0,\n\t\t\t\tcreationDate: 0\n\t\t\t} as UserCredentials<T>)\n\t\t}\n\t}\n\n\tprivate pendingPromises: Promise<any>[] = []\n\tprivate _loggedUser: UserCredentials<{}> | undefined\n\tprivate notifyChange: (( userCredentials: UserCredentials<{}> | undefined ) => void ) | undefined\n\tprivate _fakeRegisteredUsers: Collection<UserCredentials<{}>> = {}\n}","import { Persistent, PersistentObject } from '../persistent/persistent'\n\n\nexport type CloudFunction<P,R> = ( param?: P) => Promise<R>\n\nexport interface CloudFunctionsService {\n\tretrieveFunction<P, R>( cloudFunction: string ): CloudFunction<P, R>\n\tcallFunction<P,R>( func: CloudFunction<P, R>, params: P ): Promise<R>\n}\n\nexport class CloudFunctions {\n\tprivate constructor() {}\n\n\tstatic error = { shouldBeRegistered: 'You should register a cloud functions service with useCloudFunctionsService static method before using CloudFunctions.' }\n\n\tstatic useCloudFunctionsService( cloudFunctionsService: CloudFunctionsService ) {\n\t\tif ( this._cloudFunctionsService != cloudFunctionsService ) {\n\t\t\tthis._cloudFunctionsService = cloudFunctionsService\n\t\t}\n\t}\n\n\tstatic get instance() {\n\t\tif ( !this._cloudFunctionsService ) throw new Error( CloudFunctions.error.shouldBeRegistered )\n\t\treturn CloudFunctions._instance || ( CloudFunctions._instance = new CloudFunctions() )\n\t}\n\n\tgetRawFunction<P, R>( cloudFunction: string ): CloudFunction<P,R> {\n\t\treturn CloudFunctions._cloudFunctionsService.retrieveFunction( cloudFunction )\n\t}\n\n\tgetFunction<P, R=void>( cloudFunction: string ): CloudFunction<P,R> {\n\t\tconst callFunction = CloudFunctions._cloudFunctionsService.callFunction\n\t\tconst func = this.getRawFunction<P, R>( cloudFunction )\n\n\t\treturn async ( param: P ) => {\n\t\t\tconst result = await callFunction( func, this.processParam( param ) )\n\t\t\treturn this.processResult( result )\n\t\t}\n\t}\n\n\tprivate processParam<P>( param: P ): P | PersistentObject<P & Persistent> {\n\t\tif ( param === undefined || param === null ) return undefined!\n\n\t\tif ( param instanceof Persistent ) return param.toObject()\n\n\t\tif ( Array.isArray( param ) ) {\n\t\t\treturn param.map( p => this.processParam( p ) ) as unknown as P\n\t\t}\n\n\t\tif ( typeof param === 'object' ) {\n\t\t\treturn Object.entries( param ).reduce(( newParam, [ key, value ])=>{\n\t\t\t\tnewParam[ key ] = this.processParam( value )\n\t\t\t\treturn newParam\n\t\t\t}, {}) as P\n\t\t}\n\n\t\treturn param\n\t}\n\n\tprivate processResult<R>( value: R | PersistentObject<R & Persistent> ): R {\n\t\tif ( value === undefined || value === null ) return undefined!\n\n\t\tif ( ( value as PersistentObject<R & Persistent> ).__className ) {\n\t\t\treturn Persistent.createInstance( value as PersistentObject<R & Persistent> ) as R\n\t\t}\n\n\t\tif ( Array.isArray( value ) ) {\n\t\t\treturn value.map( elem => this.processResult( elem ) ) as unknown as R\n\t\t}\n\n\t\tif ( typeof value === 'object' ) {\n\t\t\treturn Object.entries( value ).reduce((newVal, [ key, val ]) => {\n\t\t\t\tnewVal[ key ] = this.processResult( val )\n\t\t\t\treturn newVal\n\t\t\t}, {}) as R\n\t\t}\n\n\t\treturn value as R\n\t}\n\n\tprivate static _cloudFunctionsService: CloudFunctionsService\n\tprivate static _instance: CloudFunctions\n}","import { CloudFunction, CloudFunctionsService } from './cloud-functions'\n\ninterface FunctionCollection { \n\t[key: string]: CloudFunction<any,any>\n}\n\nexport class CloudFunctionsMock implements CloudFunctionsService {\n\tconstructor( registeredFunctions: FunctionCollection ) {\n\t\tthis._registeredFunctions = registeredFunctions\n\t}\n\n\tretrieveFunction<P, R>( cloudFunction: string ): CloudFunction<P,R> {\n\t\tconst func = this._registeredFunctions[ cloudFunction ]\n\t\tif ( !func ) throw new Error( `Cloud function ${ cloudFunction } is not registered.` )\n\t\treturn func\n\t}\n\n\tcallFunction<P, R>( func: CloudFunction<P, R>, params: P ): Promise<R> {\n\t\treturn func( params )\n\t}\n\n\tprivate _registeredFunctions: FunctionCollection\n}","import { UserCredentials } from '../auth/user-auth-types'\n\nexport interface CustomCredentials {\n\t[ key: string ]: unknown\n}\n\nexport abstract class ServerAuthService {\n\tabstract setCustomCredentials<T extends CustomCredentials>( userId: string, customCredentials: T ): Promise<void>\n\tabstract getUser<T extends CustomCredentials>( userId: string ): Promise<UserCredentials<T> | undefined>\n\tabstract updateUser<T extends CustomCredentials>( userId: string, credentials: Partial<UserCredentials<T>> ): Promise<UserCredentials<T>>\n\tabstract deleteUser( userId: string ): Promise<void>\n}\n\nexport class ServerAuth extends ServerAuthService {\n\tstatic error = { shouldBeRegistered: 'You should register a Server Auth service before using the Server Auth.' }\n\n\tprotected constructor(){ super() }\n\n\tstatic useServerAuthService( authService: ServerAuthService ) {\n\t\tif ( ServerAuth._authService != authService ) {\n\t\t\tServerAuth._authService = authService\n\t\t\tthis._instance = undefined\n\t\t}\n\t}\n\n\tstatic get instance() {\n\t\tif ( !ServerAuth._authService ) throw new Error( ServerAuth.error.shouldBeRegistered )\n\t\treturn this._instance || (this._instance = new ServerAuth() )\n\t}\n\t\n\tgetUser<T extends CustomCredentials>( userId: string ): Promise<UserCredentials<T> | undefined> {\n\t\treturn ServerAuth._authService.getUser( userId )\n\t}\n\n\tupdateUser<T extends CustomCredentials>( userId: string, credentials: Partial<UserCredentials<T>> ): Promise<UserCredentials<T>> {\n\t\treturn ServerAuth._authService.updateUser( userId, credentials )\n\t}\n\t\n\tsetCustomCredentials<T extends CustomCredentials>( userId: string, customCredentials: T ): Promise<void> {\n\t\treturn ServerAuth._authService.setCustomCredentials( userId, customCredentials )\n\t}\n\n\tdeleteUser( userId: string ) {\n\t\treturn ServerAuth._authService.deleteUser( userId )\n\t}\n\n\tprivate static _instance: ServerAuth | undefined = undefined\n\tprivate static _authService: ServerAuthService\n}","import { UserCredentials } from '../auth/user-auth-types'\nimport { Collection } from '../types/utility-types'\nimport { ServerAuthService, CustomCredentials } from './server-auth'\n\nexport class ServerAuthMock extends ServerAuthService {\n\tconstructor( userCredentials: Collection<UserCredentials<{}>> ) {\n\t\tsuper()\n\t\tthis._userCredentials = userCredentials\n\t}\n\n\tgetUser<T extends CustomCredentials>( userId: string ): Promise<UserCredentials<T> | undefined> {\n\t\tif ( !this._userCredentials[ userId ] ) Promise.resolve( undefined )\n\n\t\treturn Promise.resolve( this._userCredentials[ userId ] as UserCredentials<T> )\n\t}\n\n\tsetCustomCredentials<T extends CustomCredentials>( userId: string, customCredentials: T ): Promise<void> {\n\t\tconst userCredentials = this._userCredentials[ userId ]\n\t\tif ( !userCredentials ) throw new Error( `User ${ userId } not found in the auth system` )\n\t\tuserCredentials.customData = { ...customCredentials }\n\n\t\treturn Promise.resolve()\n\t}\n\n\tupdateUser<T extends CustomCredentials>( userId: string, credentials: Partial<UserCredentials<T>> ): Promise<UserCredentials<T>> {\n\t\tthis._userCredentials[ userId ] = {\n\t\t\t...this._userCredentials,\n\t\t\t...credentials,\n\t\t\tid: userId\n\t\t} as UserCredentials<T>\n\n\t\treturn Promise.resolve( this._userCredentials[ userId ] as UserCredentials<T> )\n\t}\n\n\tdeleteUser( userId: string ): Promise<void> {\n\t\tdelete this._userCredentials[ userId ]\n\t\treturn Promise.resolve()\n\t}\n\n\tget userCredentials() {\n\t\treturn this._userCredentials\n\t}\n\n\tprivate _userCredentials: Collection<UserCredentials<{}>>\n}\n","import { PropPath, PropPathType } from '../types/utility-types'\n\n/**\n * A map of key-value pairs\n * @param varName the name of the variable\n * @param value the value of the variable\n */\nexport interface Values {\n\t[ varName: string ]: string;\n}\n\n/**\n * Replaces keys found in a string for its values. The keys should be inserted \n * inside brackets ${ key } as is done in the string template literals substitutions\n * @param text the string template\n * @param values an object with key-value pairs\n * @returns the string filled with corresponding values\n * @example\n * const text = 'Hello ${name}, how are you ${ action }?'\n * const values = { name: 'John', action: 'today' }\n * const result = replaceValue( text, values )\n * // result = 'Hello John, how are you today?'\n */\nexport function replaceValue( text: string | undefined | null, values: Values ): string {\n\tif ( !text ) return ''\n\t\n\treturn text.replace(/\\${\\s*(\\w*)\\s*}/g, function( _match , group){\n\t\treturn values[ group ] || '';\n\t});\n}\n\n/**\n * Transforms a string to a camel case format (camelCaseFormat)\n * @param str the string to transform. It can be a string with spaces or a \n * snake case format\n * @returns the camel case transformed string\n * @example\n * const str = 'snake-case-format'\n * const result = camelCase( str )\n * // result = 'snakeCaseFormat'\n */\nexport function camelCase( str: string | undefined | null ) {\n\tif ( !str ) return ''\n\n\treturn str.replace(\n\t\t/([-_ ][\\w])/g,\n\t\tgroup => group.toUpperCase().replace('-', '').replace('_', '').replace(' ', '')\n\t)\n}\n\n/**\n * Transforms a string in to a snake case format (snake-case-format)\n * @param str the string to transform. It can be a string with spaces or a camel\n * case format\n * @param snakeChar the character used to separate words. If the passed string is\n * in camel case and the snakeChar is a space, this will transform the came case\n * string in to a regular spaced string\n * @returns the snake case transformed string\n * @example\n * const str = 'camelCaseFormat'\n * const result = snakeCase( str )\n * // result = 'camel-case-format'\n */\nexport function snakeCase( str: string | undefined | null, snakeChar: string = '-' ) {\n\tif ( !str ) return ''\n\tconst replaced = str.slice(1).replace(/( |[A-Z])/g, g => g===' '? '-' : snakeChar + g[0]!.toLowerCase() )\n\treturn str[0]!.toLocaleLowerCase() + replaced.replace(/--/g, '-')\n}\n\n/**\n * Gets the value of the supproperty in the passed object\n * \n * @param obj the object containing the subproperty \n * @param path a string containing the subproperty path in dotted notation\n * @returns the value of the supproperty in the passed object\n * @example\n * const obj = { a: { b: { c: 1 } } }\n * const path = 'a.b.c'\n * const result = getDeepValue( obj, path )\n * // result = 1\n */\nexport function getDeepValue<T extends {}, P extends PropPath<T> & string>( obj: T, path: P ): PropPathType<T, P> {\n\treturn ( path as string ).split('.').reduce(( acc: {}, prop: string ) => acc[ prop ], obj )\n}\n"],"names":["Observable","callback","event","subs","byteToHex","i","unsafeStringify","arr","offset","getRandomValues","rnds8","rng","randomUUID","native","v4","options","buf","rnds","_a","_Persistent","className","factory","annotation","derivedFrom","obj","id","uuid","value","prop","propName","propInfo","validator","instance","rootCollections","propValue","item","ref","emptyInstance","newObject","key","val","ownerInstance","storeInCollection","cachedProps","forcedObject","collections","collectionName","document","e","stringifiedObj","_key","registeredClassName","referencesWithStoredProps","propsWithStoredValue","__decorateClass","persistent","Persistent","target","property","persistentParser","persistentReferenceAt","collectionPath","persistentReference","persistentReferenceWithCachedProps","propTypeName","persistentPureReference","persistentPureReferenceWithCachedProps","registerPersistentClass","constructor","registerLegacyClassName","legacyName","searchableArray","required","requiredWithValidator","EntropicComponent","listenerCallback","pName","arrayPropName","element","isUnique","isEqual","originalLength","_Model","stream","persistentClass","subCollection","resolve","reject","data","error","Query","queryObject","objectType","limit","from","operations","operation","DataSource","v","Model","model","operator","aggregate","_b","_c","propertyPath","props","result","classId","maxDocs","propertyName","order","_Store","dataSource","populateItem","populated","prevVal","Store","config","collectionsToWatch","handlers","collectionNameToListen","listener","collectionPathToListen","path","propPath","propsToUpdate","propWithOwner","query","persistentPropName","oldValue","newValue","JsonDataSource","jsonRawData","rawDataStore","miliSeconds","collection","rawDataArray","prevDocs","processMethod","amount","docs","a","b","queryOperations","queryOperation","doc","queryOperator","propertyValue","propVal","promise","p","_CloudStorage","cloudStorageProviderName","providerName","provider","CloudStorage","registerCloudStorage","MockCloudStorage","pathToMockFiles","fullPath","reference","StoredFileEvent","StoredFileEvent2","StoredFile","fileName","progress","cloudStorageProvider","dataToStore","AuthService","_Auth","userCredentials","authService","singData","email","password","verificationLink","onChange","Auth","AuthMock","signData","authProvider","fakeUser","user","_password","_verificationLink","_CloudFunctions","cloudFunctionsService","cloudFunction","callFunction","func","param","newParam","elem","newVal","CloudFunctions","CloudFunctionsMock","registeredFunctions","params","ServerAuthService","_ServerAuth","userId","credentials","customCredentials","ServerAuth","ServerAuthMock","replaceValue","text","values","_match","group","camelCase","str","snakeCase","snakeChar","replaced","g","getDeepValue","acc"],"mappings":"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","x_google_ignoreList":[1,2,3,4]}
1
+ {"version":3,"file":"entropic-bond.js","sources":["../src/observable/observable.ts","../node_modules/uuid/dist/esm-browser/stringify.js","../node_modules/uuid/dist/esm-browser/rng.js","../node_modules/uuid/dist/esm-browser/native.js","../node_modules/uuid/dist/esm-browser/v4.js","../src/persistent/persistent.ts","../src/persistent/entropic-component.ts","../src/store/model.ts","../src/store/store.ts","../src/store/data-source.ts","../src/store/json-data-source.ts","../src/cloud-storage/cloud-storage.ts","../src/cloud-storage/mock-cloud-storage.ts","../src/cloud-storage/stored-file.ts","../src/auth/auth.ts","../src/auth/auth-mock.ts","../src/cloud-functions/cloud-functions.ts","../src/cloud-functions/cloud-functions-mock.ts","../src/server-auth/server-auth.ts","../src/server-auth/server-auth-mock.ts","../src/utils/utils.ts"],"sourcesContent":["export type Callback<T> = ( event: T ) => void\nexport type Unsubscriber = ()=>void\n\n/**\n * Implements the Observer pattern.\n * The Observable class is used to notify a list of subscribers when an event occurs.\n * The subscribers are callback functions that are called when the event occurs.\n * The event is passed as a parameter to the callback function.\n * @example\n * // Create an observable\n * const observable = new Observable<number>()\n * // Subscribe a listener\n * const unsubscribe = observable.subscribe( event => console.log( event ) )\n * // Notify the subscribers\n * observable.notify( 1 )\n * // Unsubscribe the listener\n * unsubscribe()\n */\nexport class Observable<T> {\n\n\t/**\n\t * Subscribes a listener callback function. On every notification, \n\t * the listener callback will be called with an event as a parameter if sent.\n\t * \n\t * @param callback the listener callback\n\t * @returns a function to unsubscribe the listener from further notifications\n\t */\n\t subscribe( callback: Callback<T> ): Unsubscriber {\n\t\tthis.subscribers.add(callback)\n\t\treturn ()=>this.unsubscribe( callback )\n\t}\n\n\t/**\n\t * Removes the callback from the notification list.\n\t * \n\t * @param listenerCallback the listener callback to remove\n\t */\n\tunsubscribe( callback: Callback<T> ) {\n\t\tthis.subscribers.delete( callback )\n\t}\n\n\t/**\n\t * Notifies all the subscribers with the event passed as parameter.\n\t * \n\t * @param event the event passed to all subscribers.\n\t */\n\tnotify( event?: T ) {\n\t\tthis.subscribers.forEach(subs => subs(event!))\n\t}\n\n\t/**\n\t * Returns the number of subscribers.\n\t * \n\t * @returns the number of subscribers\n\t * @example\n\t * const observable = new Observable<number>()\n\t * observable.subscribe( event => console.log( event ) )\n\t * observable.subscribe( event => console.log( event ) )\n\t * observable.subscribe( event => console.log( event ) )\n\t * console.log( observable.subscribersCount ) // 3\n\t */\n\tget subscribersCount() {\n\t\treturn this.subscribers.size\n\t}\n\n\tprivate subscribers: Set<Callback<T>> = new Set()\n}","import validate from './validate.js';\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n //\n // Note to future-self: No, you can't remove the `toLowerCase()` call.\n // REF: https://github.com/uuidjs/uuid/pull/677#issuecomment-1757351351\n return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n var uuid = unsafeStringify(arr, offset);\n // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;","// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\n\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n return getRandomValues(rnds8);\n}","var randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);\nexport default {\n randomUUID\n};","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n offset = offset || 0;\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;","import { v4 as uuid } from 'uuid'\nimport { ClassPropNames, ClassPropNamesOfType, Primitive, SomeClassProps, UnderscoredProp } from '../types/utility-types'\n\nexport type PersistentConstructor = new () => Persistent\n\ninterface FactoryMap {\n\t[ id: string ]: {\n\t\tfactory: PersistentConstructor\n\t\tannotation: unknown\n\t}\n}\n\n/**\n * The corresponding type of the plain object of a persistent class.\n */\nexport type PersistentObject<T extends Persistent> = Omit<SomeClassProps<T>, 'className'> & Partial<DocumentReference> & {\n\t__className: string\n\t__rootCollections?: Collections\n}\n\nexport type PersistentObjectWithId<T extends Persistent> = PersistentObject<T> & {\n\tid: string\n}\n\n/**\n * The type of the plain object of a persistent class for all the nested properties.\n */\nexport type MakePersistentObjects<T> = {\n [A in keyof T]: T[A] extends Persistent? PersistentObject<T[A]> : MakePersistentObjects<T[A]>\n}\n\n/**\n * A collection of document objects typically returned by Persistent.toObject()\n * @see Persistent.toObject\n */\nexport type Collections = {\n\t[ collectionPath: string ]: PersistentObjectWithId<Persistent>[] | undefined\n}\n\n/**\n * Stores information about a reference in another collection.\n */\nexport interface DocumentReference {\n\tid: string\n\t__className: string\n\t__documentReference: {\n\t\tstoredInCollection: string\n\t}\n}\n\ntype PersistentPropertyCollection = {\n\t[className: string]: PersistentProperty[]\n}\n\n/**\n * A class that provides several methods to serialize and deserialize objects.\n */\nexport class Persistent {\n\n\t/**\n\t * Registers a class to be used by the persistence engine.\n\t * @param className the name of the class to be registered\n\t * @param factory the constructor of the registered class\n\t * @param annotation an annotation associated with the class\n\t */\n\tstatic registerFactory( className: string, factory: PersistentConstructor, annotation?: unknown ) {\n\t\tthis._factoryMap[ className ] = { factory, annotation }\n\t}\n\n\t/**\n\t * Returns the constructor of a registered class\n\t * @param className the name of the class to be retrieved\n\t * @returns the constructor of the class\n\t * @throws an error if the class is not registered\n\t * @see registerFactory\n\t * @see registeredClasses\n\t * @see classesExtending\n\t * @see annotations\n\t */\n\tstatic classFactory( className: string | undefined ) {\n\t\tif ( !className ) throw new Error( `You should provide a class name.` )\n\t\tif ( !this._factoryMap[ className ] ) throw new Error( `You should register class ${ className } prior to use.` )\n\t\treturn this._factoryMap[ className ]!.factory\n\t}\n\n\t/**\n\t * Returns the names of all registered classes\n\t * @returns the names of all registered classes\n\t * @see registerFactory\n\t * @see classFactory\n\t */\n\tstatic registeredClasses() {\n\t\treturn Object.keys( this._factoryMap )\n\t}\n\n\t/**\n\t * Returns the names of all registered classes that extend a given class\n\t * @param derivedFrom the class to be extended\n\t * @returns the names of all registered classes that extend the given class\n\t * @see registerFactory\n\t * @see classFactory\n\t */\n\tstatic classesExtending( derivedFrom: PersistentConstructor | Function ) {\n\t\treturn Object.entries( this._factoryMap )\n\t\t\t.filter(([ , obj ]) => new ( obj.factory ) instanceof derivedFrom )\n\t\t\t.map(([ className ]) => className )\n\t}\n\n\t/**\n\t * Returns the annotation associated with a registered class\n\t * @param className the name of the class to be retrieved\n\t * @returns the annotation associated with the class\n\t * @throws an error if the class is not registered\n\t * @see registerFactory\n\t */\n\tstatic annotations( className: string | Persistent | PersistentConstructor ) {\n\t\tif ( className instanceof Persistent ) className = className.className\n\t\telse if ( typeof className === 'string' ) className\n\t\telse className = new className().className\n\n\t\tif ( !this._factoryMap[ className ] ) throw new Error( `You should register class ${ className } prior to use.` )\n\t\treturn this._factoryMap[ className ]!.annotation\n\t}\n\n\t/**\n\t * Returns a new instance of Persistent class.\n\t * @param className the initial id of this instance. If not provided, a new id will be generated\n\t */\n\tconstructor( id: string = uuid() ) {\n\t\tthis._id = id\n\t}\n\n\t/**\n\t * Gets the class name of this instance.\n\t */\n\tget className(): string {\n\t\treturn this[ '__className' ];\n\t}\n\n\t/**\n\t * Sets the id of this instance.\n\t * @param value the id of this instance\n\t */\n\tprotected setId( value: string ) {\n\t\tthis._id = value\n\t}\n\n\t/**\n\t * Returns the id of this instance.\n\t * @returns the id of this instance\n\t */\n\tget id() {\n\t\treturn this._id;\n\t}\n\n\t/**\n\t * This method is called by the persistence engine when the instance has been\n\t * just serialized. It is called after the properties are initialized with \n\t * serialized data.\n\t */\n\tprotected afterDeserialize() {}\n\n\t/**\n\t * This method is called by the persistence engine before the instance is\n\t * serialized. \n\t */\n\tprotected beforeSerialize() {}\n\n\t/**\n\t * Returns an array of the persistent properties of this instance.\n\t * @returns an array of the persistent properties of this instance\n\t */\n\tgetPersistentProperties(): readonly PersistentProperty[] {\n\t\tif ( !this._persistentProperties ) return []\n\t\treturn this._persistentProperties.map( prop => ({\n\t\t\t...prop,\n\t\t\tname: prop.name.slice( 1 ) \n\t\t}))\n\t}\n\n\t/**\n\t * Get the property information of this instance\n\t * @param propName the persistent property name\n\t * @returns the property information\n\t */\n\tgetPropInfo<T extends this>( propName: ClassPropNames<T> ): PersistentProperty {\n\t\tconst propInfo = this.getPersistentProperties().find( prop => prop.name === propName as string )\n\t\tif ( !propInfo ) throw new Error( `Property \"${ propName as string }\" has not been registered.` )\n\t\treturn propInfo\n\t}\n\n\t/**\n\t * Query if the property is required\n\t * To mark a property as required, use the @required decorator\n\t * @param propName the persistent property name\n\t * @returns true if the property is required\n\t * @see required\n\t */\n\tisRequired<T extends this>( propName: ClassPropNames<T> ): boolean {\n\t\tconst validator = this.getPropInfo( propName ).validator\n\t\treturn validator !== undefined && validator !== null\n\t}\n\n\t/**\n\t * Query if the property value is valid\n\t * Define the validator function using the @required decorator\n\t * @param propName the persistent property name\n\t * @returns true if the property value is valid using the validator function\n\t * passed to the @required decorator\n\t * @see required\n\t */\n\tisPropValueValid<T extends this>( propName: ClassPropNames<T> ): boolean {\n\t\tconst propInfo = this.getPropInfo( propName )\n\t\tif ( !propInfo.validator ) return true\n\t\treturn propInfo.validator( this[ propInfo.name ], propInfo, this )\n\t}\n\n\t/**\n\t * Copy the persistent properties of the given instance to this instance. \n\t * The property `id` will be ignored.\n\t * Only the properties that are not null or undefined will be copied.\n\t * @param instance the instance to be copied\n\t * @returns this instance\n\t * @see fromObject\n\t * @see toObject\n\t */\n\tclone( instance: Persistent ): this {\n\t\tconst obj = instance.toObject() as any\n\t\tdelete obj['id']\n\t\treturn this.fromObject( obj )\n\t}\n\n\t/**\n\t * Initializes the persistent properties of this instance from the properties \n\t * of given object.\n\t * @param obj the object to be copied\n\t * @returns this instance\n\t * @see clone\n\t * @see toObject\n\t */\n\tfromObject( obj: Partial<PersistentObject<this>> |{}): this {\n\t\tthis.fromObj( obj )\n\t\tthis.afterDeserialize()\n\n\t\treturn this\n\t}\n\n\tprivate fromObj( obj: Partial<PersistentObject<this>> | {}) {\n\t\tif ( !this._persistentProperties ) return this\n\n\t\tthis._persistentProperties.forEach( prop => {\n\t\t\tconst propName = this.removeUnderscore( prop )\n\n\t\t\tconst value = obj[ propName ]\n\t\t\tif ( value !== undefined && value !== null ) {\n\t\t\t\tthis[ prop.name ] = this.fromDeepObject( value )\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Returns a plain object representation of this instance.\n\t * Only the properties that are not null or undefined will be copied.\n\t * @returns a plain object representation of this instance\n\t * @see fromObject\n\t * @see clone\n\t */\n\ttoObject(): PersistentObject<this> {\n\t\tconst rootCollections: Collections = {}\n\t\tconst obj = this.toObj( rootCollections )\n\t\tthis.pushDocument( rootCollections, this.className, obj )\n\n\t\treturn {\n\t\t\t...obj,\n\t\t\t__rootCollections: rootCollections\n\t\t}\n\t}\n\n\tprivate toObj( rootCollections: Collections ): PersistentObject<this> {\n\t\tif ( !this._persistentProperties ) return {} as PersistentObject<this>\n\t\tthis.beforeSerialize()\n\n\t\tconst obj: PersistentObject<this> = {} as any\n\t\tif ( !this.className ) throw new Error( 'You should register this class prior to streaming it.' )\n\n\t\tthis._persistentProperties.forEach( prop => {\n\t\t\tconst propValue = this[ prop.name ]\n\t\t\tconst propName = this.removeUnderscore( prop )\n\t\t\t\n\t\t\tif ( propValue !== undefined && propValue !== null ) {\n\n\t\t\t\tif ( prop.isReference ) {\n\t\t\t\t\tobj[ propName ] = this.toReferenceObj( prop, rootCollections )\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tobj[ propName ] = this.toDeepObj( propValue, rootCollections )\n\t\t\t\t}\n\n\t\t\t\tif ( prop.searchableArray ) {\n\t\t\t\t\tobj[ Persistent.searchableArrayNameFor( propName ) ] = propValue.map(( value: PersistentObject<Persistent> ) => value.id )\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tobj[ '__className' ] = this.className\n\n\t\treturn obj\n\t}\n\n\tstatic searchableArrayNameFor( propName: string ) {\n\t\treturn `__${ propName }_searchable`\n\t}\n\n\tprivate fromDeepObject( value: unknown ) {\n\t\tif ( value === undefined || value === null ) return value\n\t\t\n\t\tif ( Array.isArray( value ) ) {\n\t\t\treturn value.map( item => this.fromDeepObject( item ) )\n\t\t}\n\n\t\tif ( value[ '__documentReference' ] ) {\n\t\t\tconst ref: DocumentReference = value as DocumentReference\n\t\t\tconst emptyInstance = Persistent.createInstance( ref )\n\t\t\t// emptyInstance._id = ref.id\n\t\t\temptyInstance['__documentReference'] = value[ '__documentReference' ]\n\t\t\treturn emptyInstance\n\t\t}\n\n\t\tif ( value[ '__className' ] ) {\n\t\t\treturn Persistent.createInstance( value as PersistentObject<Persistent> )\n\t\t}\n\n\t\tif ( typeof value === 'object' ) {\n\t\t\tconst newObject = {}\n\n\t\t\tObject.entries( value ).forEach(\n\t\t\t\t( [ key, value ] ) => newObject[ key ] = this.fromDeepObject( value )\n\t\t\t)\n\n\t\t\treturn newObject\n\t\t}\n\n\t\treturn value\n\t}\n\n\tprivate toDeepObj( value: any, rootCollections: Collections ) {\n\t\tif ( value === null || value === undefined ) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tif ( Array.isArray( value ) ) {\n\t\t\treturn value.map( item => this.toDeepObj( item, rootCollections ) )\n\t\t}\n\n\t\tif ( value[ '__documentReference' ] ) return value\n\t\t\n\t\tif ( value instanceof Persistent ) {\n\t\t\treturn value.toObj( rootCollections )\n\t\t}\n\n\t\tif ( typeof value === 'object' ) {\n\t\t\tconst newObject = {}\n\n\t\t\tObject.entries( value ).forEach(\n\t\t\t\t( [ key, val ] ) => newObject[ key ] = this.toDeepObj( val, rootCollections )\n\t\t\t)\n\n\t\t\treturn newObject\n\t\t}\n\n\t\treturn value\n\t}\n\n\tstatic collectionPath( ownerInstance: Persistent, prop: PersistentProperty ) {\n\t\tlet storeInCollection: string\n\n\t\tif ( typeof prop.storeInCollection === 'function' ) {\n\t\t\tstoreInCollection = prop.storeInCollection( ownerInstance, prop )\n\t\t}\n\t\telse {\n\t\t\tstoreInCollection = prop.storeInCollection ?? ownerInstance.className\n\t\t}\n\t\treturn storeInCollection\n\t}\n\n\tprivate toReferenceObj( prop: PersistentProperty, rootCollections: Collections ) {\n\t\tconst propValue: Persistent | Persistent[] = this[ prop.name ]\n\t\t\n\t\tif ( Array.isArray( propValue ) ) {\n\n\t\t\treturn propValue.map( item => {\n\t\t\t\tif ( !prop.isPureReference ) {\n\t\t\t\t\tthis.pushDocument( rootCollections, Persistent.collectionPath( item, prop ), item )\n\t\t\t\t}\n\t\t\t\treturn this.buildRefObject( item, Persistent.collectionPath( item, prop ), prop.cachedProps )\n\t\t\t})\n\n\t\t}\n\t\telse {\n\t\t\tif ( !prop.isPureReference ) {\n\t\t\t\tthis.pushDocument( rootCollections, Persistent.collectionPath( propValue, prop ), propValue )\n\t\t\t}\n\t\t\treturn this.buildRefObject( propValue, Persistent.collectionPath( propValue, prop ), prop.cachedProps )\n\n\t\t}\n\t}\n\n\tprivate buildRefObject( value: Persistent, storeInCollection: string, cachedProps?: ClassPropNames<Persistent>[] ): DocumentReference {\n\t\tconst forcedObject = cachedProps?.reduce( ( obj, propName ) => {\n\t\t\tif ( value[ propName ] !== undefined ) obj[ propName ] = value[ propName ]\n\t\t\treturn obj\n\t\t}, {})\n\n\t\treturn {\n\t\t\tid: value.id,\n\t\t\t__className: value.className || value['__className'],\n\t\t\t__documentReference: {\n\t\t\t\tstoredInCollection: storeInCollection\n\t\t\t}, \n\t\t\t...forcedObject\t\n\t\t}\n\t}\n\n\tprivate pushDocument( collections: Collections, collectionName: string, value: DocumentReference | Persistent | PersistentObject<this> ) {\n\t\tif ( '__documentReference' in value && value.__documentReference ) return\n\t\t\n\t\tif ( !collections[ collectionName ] ) collections[ collectionName ] = []\n\t\tconst document = this.toDeepObj( value, collections )\n\t\tcollections[ collectionName ]!.push( document )\n\t}\n\n\tprivate removeUnderscore( prop: PersistentProperty ) {\n\t\treturn prop.name.slice(1)\n\t}\n\n\tstatic createReference<T extends Persistent>( obj: PersistentObject<T> | string ): T {\n\t\tconst instance = Persistent.createInstance( obj )\n\t\tinstance['__documentReference'] = obj['__documentReference'] || { storedInCollection: instance.className }\n\t\treturn instance\n\t}\n\n\tstatic createInstance<T extends Persistent>( obj: PersistentObject<T> | string ): T {\n\t\tif ( typeof obj === 'string' ) {\n\t\t\treturn new ( Persistent.classFactory( obj ) ) as T\n\t\t}\n\t\telse {\n\t\t\ttry {\n\t\t\t\tconst instance = new ( Persistent.classFactory( obj.__className ) )\n\t\t\t\treturn instance.fromObject( obj ) as T\n\t\t\t}\n\t\t\tcatch ( e ) {\n\t\t\t\tconst stringifiedObj = Object.entries( obj )\n\t\t\t\t\t.filter(([ _key, value ])=> value !== undefined && value !== null && typeof value !== 'function' )\n\t\t\t\t\t.map(([ key, value ])=>`${ key }: ${ value }` )\n\t\t\t\t\t.join( ',\\n\\t' )\n\t\t\t\tthrow new Error( `${ e }\\n-----> Class name not found in object:\\n{\\n\\t ${ stringifiedObj } \\n}\\n` )\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic propInfo<T extends Persistent>( registeredClassName: string, propName: ClassPropNames<T> ): PersistentProperty {\n\t\tconst inst = Persistent.createInstance( registeredClassName )\n\t\treturn inst.getPropInfo( propName )\n\t}\n\n\t/**\n\t * Retrieves a collection of references with the properties that are stored in the reference object\n\t * @returns the references collection\n\t */\n\tstatic getSystemRegisteredReferencesWithCachedProps(): PersistentPropertyCollection {\n\t\tconst systemRegisteredClasses = Persistent.registeredClasses()\n\t\tconst referencesWithStoredProps = systemRegisteredClasses.reduce(( referencesWithStoredProps, className ) => {\n\t\t\tconst inst = Persistent.createInstance( className )\n\t\t\tconst propsWithStoredValue = inst.getPersistentProperties().filter( \n\t\t\t\tpropInfo => propInfo.cachedProps\n\t\t\t)\n\t\t\tif ( propsWithStoredValue.length > 0 ) referencesWithStoredProps[className] = propsWithStoredValue\n\t\t\treturn referencesWithStoredProps\n\t\t}, {} as PersistentPropertyCollection )\n\t\t\n\t\treturn referencesWithStoredProps\n\t}\n\n\t@persistent private _id: string\n\tprivate _persistentProperties: PersistentProperty[] | undefined\n\tprivate static _factoryMap: FactoryMap = {}\n}\n\n///////////////////////////////////\n//Decorators\n///////////////////////////////////\n\ntype CollectionPathCallback = ( value: Persistent, prop: PersistentProperty ) => string\ntype ValidatorFunction<T extends Persistent, P extends ClassPropNames<T>> = ( value: T[P], property: PersistentProperty, persistentInstance: T ) => boolean\n\nexport interface PersistentProperty {\n\tname: string\n\tisReference?: boolean\n\tisPureReference?: boolean\n\tstoreInCollection?: string | CollectionPathCallback\n\tsubCollection?: string\n\tcachedProps?: ClassPropNames<Persistent>[]\n\ttoObjectSpecial?: ( classObj: any ) => any\n\tfromObjectSpecial?: ( obj: any ) => any\n\tsearchableArray?: boolean\n\tvalidator?: ValidatorFunction<any, any>\n\ttypeName?: string | string[]\n}\n\n/**\n * Decorator for a property that you want to persist.\n */\nexport function persistent( target: Persistent, property: string ) {\n\treturn persistentParser()( target, property );\n}\n\n/**\n * Decorator for a property that is a reference to a persistent object and should be stored\n * in a specific collection.\n * @param collectionPath the path to the collection where the reference should be stored.\n * @returns \n */\nexport function persistentReferenceAt( collectionPath: string | CollectionPathCallback ) {\n\treturn function( target: Persistent, property: string ) {\n\t\treturn persistentParser({ \n\t\t\tstoreInCollection: collectionPath,\n\t\t\tisReference: true\n\t\t})( target, property )\n\t}\n}\n\n/**\n * Decorator for a property that is a reference to a persistent object. \n * The reference content is automatically stored in a collection. The collection \n * is determined by the class name of the decorated property. \n * @see persistentPureReference\n */\nexport function persistentReference( target: Persistent, property: string ) {\n\treturn persistentParser({ isReference: true })( target, property )\n}\n\n/**\n * Decorator to declare a persistent reference (see @persistentReference) that stores\n * the values in cachedProps as values in the reference object. This is useful\n * when you are not able to wait for population of referenced properties.\n * @param cachedProps the properties whose values should be stored in the reference object\n * @param storedInCollection indicates the path of the collection where this reference is stored\n */\nexport function persistentReferenceWithCachedProps<T extends Persistent>( cachedProps: ClassPropNamesOfType<T, Primitive>[], storeInCollection?: string | CollectionPathCallback, propTypeName?: string | string[] ) {\n\treturn function( target: Persistent, property: string ) {\n\t\tconst persistentProps: Partial<PersistentProperty> = { \n\t\t\tisReference: true, \n\t\t\tcachedProps: cachedProps as ClassPropNames<Persistent>[],\n\t\t\tstoreInCollection: storeInCollection,\n\t\t\ttypeName: propTypeName\n\t\t}\n\t\treturn persistentParser( persistentProps )( target, property )\n\t}\n}\n\n/**\n * Decorator for a property that is a reference to a persistent object. \n * In this case, and contrary to the @persistentReference decorator, the reference \n * contents is not stored even it has been changed. Only the reference information \n * is stored.\n * @see persistentReference\n */\n export function persistentPureReference( target: Persistent, property: string, storeInCollection?: string | CollectionPathCallback ) {\n\treturn persistentParser({ isReference: true, isPureReference: true, storeInCollection })( target, property )\n}\n\n/**\n * Decorator to declare a persistent property as a pure reference (see @persistentPureReference) that stores\n * the values of the properties listed in cachedProps as values in the reference object. This is useful\n * when you only need a few properties to be available without needing to populate the referenced property.\n * @param cachedProps the properties whose values should be stored in the reference object\n * @param storedInCollection indicates the path of the collection where this reference is stored\n * @see persistentReferenceWithCachedProps\n * @see persistentPureReference\n * @sample\n * class User extends Persistent {\n * \t@persistentPureReferenceWithCachedProps( ['name', 'email'] ) private _friend: User\n * }\n * // the reference object will contain the properties name and email of the referenced user\n * // without having to populate the _friend property\n */\nexport function persistentPureReferenceWithCachedProps<T extends Persistent>( cachedProps: ClassPropNamesOfType<T,Primitive>[], storeInCollection?: string | CollectionPathCallback, propTypeName?: string | string[] ) {\n\treturn function( target: Persistent, property: string ) {\n\t\treturn persistentParser({ \n\t\t\tisReference: true, \n\t\t\tisPureReference: true, \n\t\t\tcachedProps: cachedProps as ClassPropNames<Persistent>[], \n\t\t\tstoreInCollection: storeInCollection,\n\t\t\ttypeName: propTypeName\n\t\t})( target, property )\n\t}\n}\n\nexport function persistentParser( options?: Partial<PersistentProperty> ) {\n\treturn function( target: Persistent, property: string ) {\n\n\t\t// from: https://stackoverflow.com/questions/43912168/typescript-decorators-with-inheritance\n\t\t// should work like this in order to avoid propagation of persistent properties from one class to others\n\t\tif ( !Object.getOwnPropertyDescriptor( target, '_persistentProperties' ) ) {\n\t\t\tif ( target[ '_persistentProperties' ] ) {\n\t\t\t\ttarget[ '_persistentProperties' ] = [ ...target[ '_persistentProperties' ] ]\n\t\t\t}\n\t\t\telse target[ '_persistentProperties' ] = []\n\t\t}\n\n\t\tconst propInfo = target[ '_persistentProperties' ]!.find( prop => prop.name === property )\n\t\tif ( propInfo ) {\n\t\t\tObject.assign( propInfo, options )\n\t\t}\n\t\telse {\n\t\t\ttarget[ '_persistentProperties' ]!.push({\n\t\t\t\tname: property,\n\t\t\t\t...options\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Decorator to register a persistent class. Entropic Bond needs that you register\n * all persistent classes that you want to use in any persistent stream. \n * @param className the name of the class\n * @param annotation an optional annotation that can be used to store additional information\n */\nexport function registerPersistentClass( className: string, annotation?: unknown ) {\n\treturn ( constructor: PersistentConstructor ) => {\n\t\tPersistent.registerFactory( className, constructor, annotation )\n\t\tconstructor.prototype.__className = className\n\t}\n}\n\n/**\n * Decorator to register a legacy name for a persistent class. This is useful when you want to\n * be able to load old data that was stored with a different class name.\n * @param legacyName the legacy name of the class\n */\nexport function registerLegacyClassName( legacyName: string ) {\n\treturn ( constructor: PersistentConstructor ) => {\n\t\tPersistent.registerFactory( legacyName, constructor )\n\t}\n}\n\n/**\n * Decorator to make a `Persistent` array property searchable by the \n * persistance engine.\n * When a property is marked as searchable, the persistance engine will\n * generate internally a new property with the same name but with the suffix `_searchable`\n * and prefixed with the `_` character. This new property will contain an array\n * with the `id` of the persistent elements in the original array.\n */ \nexport function searchableArray( target: Persistent, property: string ) {\n\treturn persistentParser({ searchableArray: true })( target, property )\n}\n\n/**\n * Decorator to mark the property as required.\n * @see requiredWithValidator\n */\nexport function required( target: Persistent, property: string ) {\n\treturn persistentParser({ validator: ( value: any ) => value !== undefined && value !== null })( target, property )\n}\n\n/**\n * Decorator to mark the property as required.\n * @param validator a function that returns true if the property value is valid. \n * By default, the property is valid if it is not undefined and not null.\n * @see required\n */\nexport function requiredWithValidator<T extends Persistent, P extends ClassPropNames<T>>( validator: ValidatorFunction<T, P> = ( value: T[P] ) => value !== undefined && value !== null ) {\n\treturn function( target: T, property: UnderscoredProp<P> ) {\n\t\treturn persistentParser({ validator: validator })( target, property )\n\t}\n}\n","import { Callback, Observable, Unsubscriber } from '../observable/observable';\nimport { ClassArrayPropNames, ClassProps, Elements } from '../types/utility-types';\nimport { Persistent } from './persistent';\n\nexport type PropChangeEvent<T> = Partial<ClassProps<T>>\nexport type PropChangeCallback<T> = Callback<PropChangeEvent<T>>\ntype ArrayPropsElem<T> = Elements<T[ClassArrayPropNames<T>]>\nexport type CompareFunction<T> = ( a: ArrayPropsElem<T>, b: ArrayPropsElem<T> )=>boolean\n\n/**\n * Derived classes from EntropicComponent will have the ability to notify \n * property changes by calling one of the provided notification methods.\n * It extends Persistent class therefore EntropicComponent children will have\n * persistance through the Entropic Bond persistence mechanism\n */\nexport class EntropicComponent extends Persistent {\n\n\t/**\n\t * Subscribes a listener callback function. Every time a property is changed, \n\t * the listener callback will be called with the property change event.\n\t * \n\t * @param listenerCallback the listener callback\n\t * @returns a function to unsubscribe the listener from further notifications\n\t */\n\tonChange( listenerCallback: PropChangeCallback<this> ): Unsubscriber {\n\t\treturn this._onChange.subscribe( listenerCallback )\n\t}\n\n\t/**\n\t * Removes the listener callback subscrition from the notifications.\n\t * \n\t * @param listenerCallback the listener callback to remove\n\t */\n\tremoveOnChange( listenerCallback: PropChangeCallback<this> ) {\n\t\tthis._onChange.unsubscribe( listenerCallback )\n\t}\n\n\t/**\n\t * Changes the value of the property and notifies the subscribers about the change.\n\t * This is a helper method that can be used in the property setter.\n\t * \n\t * @param propName the name of the property to be changed\n\t * @param value the new value for the property\n\t * @returns true in case the property has been effectively changed, false otherwise\n\t */\n\tprotected changeProp<P extends keyof this>( propName: P, value: this[ P ] ): boolean {\n\t\tconst pName = '_' + String( propName );\n\n\t\tif ( this[ pName ] !== value ) {\n\t\t\tthis[ pName ] = value;\n\t\t\tthis._onChange.notify({ [ propName ]: value });\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Notifies the subscribers a property or group of properties change.\n\t * This is a helper function to be used when you want to notify property changes.\n\t * \n\t * @param event the event with the changed properties\n\t */\n\tprotected notify<T extends EntropicComponent>( event: PropChangeEvent<T> ) {\n\t\tthis._onChange.notify(event)\n\t}\n\n\t/**\n\t * Inserts a new element in an arbitrary array property of this class and \n\t * fires a change event if successfully inserted. To avoid repeated elements\n\t * to be inserted, you can pass a function that checks for inequity.\n\t * \n\t * @param arrayPropName the name of the array property of this class where you\n\t * \t\t\t\t\t\t\t\t\t\t\twant to insert the\tnew element.\n\t * @param element the element to be inserted\n\t * @param isUnique a function that checks for inequity of the two elements \n\t * \t\t\t\t\t\t\t\t\tpassed as parameter. If the returned value is true, the \n\t * \t\t\t\t\t\t\t\t\tvalue will be\tpushed into the array. When the function is \n\t * \t\t\t\t\t\t\t\t\tnot provided, the element will be inserted regardless it is\n\t * \t\t\t\t\t\t\t\t\talready in the array.\n\t * @returns the inserted element or undefined if the element was not inserted.\n\t */\n\tprotected pushAndNotify<T extends EntropicComponent>( \n\t\tarrayPropName: ClassArrayPropNames<T>, \n\t\telement: ArrayPropsElem<T>, \n\t\tisUnique?: CompareFunction<T> \n\t): ArrayPropsElem<T> | undefined {\n\n\t\tconst pName = '_' + String( arrayPropName );\n\t\tconst alreadyIn = isUnique && this[ pName ].find( \n\t\t\t( item: ArrayPropsElem<T> ) => !isUnique( item, element ) \n\t\t)\n\t\tif ( alreadyIn ) return undefined\n\n\t\tthis[ pName ].push( element )\n\t\tthis.notify({ [arrayPropName]: this[ arrayPropName as string ] })\n\t\treturn element\n\t}\n\n\t/**\n\t * Removes an element from an arbitrary array property of this class and fires\n\t * a change event on operation success.\n\t * \n\t * @param arrayPropName the name of the array property of this class where you\n\t * \t\t\t\t\t\t\t\t\t\t\twant to insert the\tnew element.\n\t * @param element the element to be inserted\n\t * @param isEqual a function that checks for equity of the two elements \n\t * \t\t\t\t\t\t\t\t\tpassed as parameter. If the returned value is true, the \n\t * \t\t\t\t\t\t\t\t\tvalue will be\tremoved from the array. \n\t * @returns the removed element or undefined if the element was not removed.\n\t */\n\tprotected removeAndNotify<T extends EntropicComponent>( \n\t\tarrayPropName: ClassArrayPropNames<T>, \n\t\telement: ArrayPropsElem<T>,\n\t\tisEqual: CompareFunction<T>\n\t): ArrayPropsElem<T> | undefined {\n\n\t\tconst pName = '_' + String( arrayPropName );\n\n\t\tconst originalLength = this[ pName ].length\n\n\t\tthis[ pName ] = this[ pName ].filter( \n\t\t\t( item: ArrayPropsElem<T> ) => !isEqual( item, element ) \n\t\t)\n\n\t\tif ( originalLength === this[ pName ].length ) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tthis.notify({ [arrayPropName]: this[ arrayPropName as string ] })\n\t\treturn element\n\t}\n\n\tprivate _onChange: Observable<PropChangeEvent<EntropicComponent>> = new Observable<PropChangeEvent<EntropicComponent>>()\n}","import { Persistent, PersistentObject } from '../persistent/persistent'\nimport { ClassPropNames, PropPath, PropPathType } from '../types/utility-types'\nimport { DataSource, QueryOperator, QueryObject, QueryOrder, DocumentObject, QueryOperation } from './data-source'\n\n/**\n * Provides abstraction to the database access. You should gain access to a Model\n * object through the Store.getModel method instead of its constructor.\n */\nexport class Model<T extends Persistent>{\n\tstatic error = { \n\t\tpersistentNeedForSubCollection: 'The document parameter for a sub-collection should be a Persistent instace',\n\t\tinvalidQueryOrder: 'Cannot add where calls after or calls'\n\t}\n\n\tconstructor( stream: DataSource, persistentClass: Persistent | string, subCollection?: string ) {\n\t\tif ( subCollection ) {\n\t\t\tif( !( persistentClass instanceof Persistent ) ) throw new Error( Model.error.persistentNeedForSubCollection )\n\n\t\t\tthis.collectionName = `${ persistentClass.className }/${ persistentClass.id }/${ subCollection }`\n\t\t}\n\t\telse {\n\t\t\tthis.collectionName = persistentClass instanceof Persistent\n\t\t\t\t? persistentClass.className \n\t\t\t\t: persistentClass\n\t\t}\n\n\t\tthis._stream = stream\n\t}\n\n\t/**\n\t * Finds an stored object in the database by its id. The field id is provided\n\t * by the Persistent parent class and it is automatically managed. Therefore,\n\t * you should obtain the id by looking at the id field of the object.\n\t * \n\t * @param id the id to look for\n\t * @param instance you can pass an instace that will be filled with the found data\n\t * @returns a promise resolving to an instance with the found data\n\t */\n\tfindById<D extends T>( id: string, instance?: D ): Promise<D | undefined> {\n\t\treturn new Promise<D | undefined>( ( resolve, reject ) => {\n\t\t\tthis._stream.findById( id, this.collectionName )\n\t\t\t\t.then(( data: PersistentObject<D> ) => {\n\t\t\t\t\tif ( data ) {\n\n\t\t\t\t\t\tif ( !instance ) instance = Persistent.createInstance( data )\n\t\t\t\t\t\telse instance.fromObject( data ) \n\n\t\t\t\t\t\tresolve( instance )\n\t\t\t\t\t}\n\t\t\t\t\telse resolve( undefined )\n\t\t\t\t})\n\t\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\t\n\t/**\n\t * Stores an object in the database\n\t * \n\t * @param instance the object instance to store\n\t * @returns a promise \n\t */\n\tsave( instance: T ): Promise<void> {\n\t\tconst obj = instance.toObject() as PersistentObject<T> & { __rootCollections: DocumentObject }\n\t\t\n\t\tif ( this.collectionName !== obj.__className ) {\n\t\t\tobj.__rootCollections[ this.collectionName ] = obj.__rootCollections[ obj.__className ]\n\t\t\tdelete obj.__rootCollections[ obj.__className ]\n\t\t}\n\t\t\n\t\treturn new Promise<void>( ( resolve, reject ) => {\n\t\t\tthis._stream.save( obj.__rootCollections ) \n\t\t\t.then( () => resolve() )\n\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\t\n\t/**\n\t * Removes an element from the database by id\n\t * @param id the id of the element to be removed\n\t * @returns a promise\n\t */\n\tdelete( id: string ): Promise<void> {\n\t\treturn new Promise<void>( ( resolve, reject ) => {\n\t\t\tthis._stream.delete( id, this.collectionName ) \n\t\t\t.then( () => resolve() )\n\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\n\t/**\n\t * Call find to retrieve a Query object used to define the search conditions\n\t * @returns a Query object\n\t */\n\tfind<U extends T>(): Query<U> {\n\t\treturn new Query<U>( this as unknown as Model<U> )\n\t}\n\n\t/**\n\t * Define the search conditions. You pass query operations and how the query\n\t * results are returned to the QueryObject\n\t * @param queryObject the QueryObject with the search constrains\n\t * @param objectType Deprecated! - restricts the search to a specific instances of the class type\n\t * @returns a promise resolving to a collection of matched documents\n\t */\n\tquery<U extends T>( queryObject: QueryObject<U> = {}, /** @deprecated */ objectType?: U | string ): Promise<U[]> {\n\t\tif ( objectType ) {\n\t\t\tconst className = objectType instanceof Persistent ? objectType.className : objectType\n\t\t\tif ( !queryObject.operations ) queryObject.operations = []\n\t\t\tqueryObject.operations.push(\n\t\t\t\t{ property: '__className', operator: '==', value: className } as any \n\t\t\t)\n\t\t}\n\n\t\treturn this.mapToInstance( \n\t\t\t() => this._stream.find( this.preprocessQueryObject( queryObject ), this.collectionName ) \n\t\t)\n\t}\n\n\t/**\n\t * Get the amount of documents matching the query\n\t * @param queryObject the QueryObject with the search constrains\n\t * @returns a promise resolving to the amount of matched documents\n\t */\n\tcount( queryObject: QueryObject<T> ): Promise<number> {\n\t\treturn this._stream.count( queryObject as unknown as QueryObject<DocumentObject>, this.collectionName )\n\t}\n\n\t/**\n\t * Get the next bunch of documents matching the last query\n\t * @param limit the max amount of documents to retrieve. If not set, uses the\n\t * last limit set\n\t * @returns a promise resolving to a collection of matched documents\n\t */\n\tnext<U extends T>( limit?: number ): Promise<U[]> {\n\t\treturn this.mapToInstance( () => this._stream.next( limit ) )\n\t}\n\n\t// /**\n\t// * Get the previous bunch of documents matching the last query\n\t// * @param limit the max amount of documents to retrieve. If not set, uses the\n\t// * last limit set\n\t// * @returns a promise resolving to a collection of matched documents\n\t// */\n\t// prev<U extends T>( limit?: number ): Promise<U[]> {\n\t// \treturn this.mapToInstance( () => this._stream.prev( limit ) )\n\t// }\n\n\tprivate mapToInstance<U extends T>( from: ()=>Promise<DocumentObject[]> ): Promise<U[]> {\n\t\treturn new Promise<U[]>( ( resolve, reject ) => {\n\t\t\tfrom()\n\t\t\t\t.then( data => resolve( \n\t\t\t\t\tdata.map( obj => Persistent.createInstance( obj as any ))\n\t\t\t\t))\n\t\t\t\t.catch( error => reject( error ) )\n\t\t})\n\t}\n\n\t/**\n\t * Normalizes the query object to match the data source requirements.\n\t * Call this method before you do any query operation on the concrete data source\n\t * @param queryObject the query object containing the query operations\n\t * @param operatorConversor a function that converts the query operators to the\n\t * operators supported by the concrete data source\n\t * @returns the normalized query object\n\t */\n\tprivate preprocessQueryObject<U>( queryObject: QueryObject<U> ): QueryObject<DocumentObject> {\n\t\tif ( Object.values( queryObject ).length === 0 ) return queryObject as unknown as QueryObject<DocumentObject>\n\n\t\tconst operations = queryObject.operations?.map( operation => {\n\t\t\tconst value = operation.value[0] ?? operation.value\n\n\t\t\tif ( DataSource.isArrayOperator( operation.operator ) && value instanceof Persistent ) {\n\t\t\t\treturn {\n\t\t\t\t\tproperty: Persistent.searchableArrayNameFor( operation.property as string ),\n\t\t\t\t\toperator: operation.operator,\n\t\t\t\t\tvalue: Array.isArray( operation.value )? operation.value.map( v => v.id ) : value.id,\n\t\t\t\t\taggregate: operation.aggregate\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn {\n\t\t\t\t\tproperty: operation.property,\n\t\t\t\t\toperator: operation.operator,\n\t\t\t\t\tvalue: operation.value instanceof Persistent ? { id: operation.value.id } : operation.value,\n\t\t\t\t\taggregate: operation.aggregate\n\t\t\t\t}\n\t\t\t}\n\t\t}) ?? []\n\n\t\treturn {\n\t\t\t...queryObject,\n\t\t\toperations\n\t\t} as QueryObject<DocumentObject>\n\t}\n\n\treadonly collectionName: string\n\tprivate _stream: DataSource\n}\n\n/**\n * The Query class is used to define the search conditions. You can chain\n * where operations to define the search conditions. The where operations\n * are stored in a QueryObject that is passed to the query method of the\n * Model class.\n */\nexport class Query<T extends Persistent> {\n\tconstructor( model: Model<T> ) {\n\t\tthis.model = model\t\n\t}\n\n\t/**\n\t * Matches all documents that the value of the property satisfies the condition\n\t * in the operator parameter. Subsequent `where` calls will be operated to the\n\t * previous ones using the AND operator\n\t * @param property the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @param aggregate if true, the query will use the logical or operator and \n\t * aggregate the results to the previous query\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.where( 'name', '==', 'John' )\n\t * query.where( 'age', '>', 18 )\n\t * query.where( 'age', '==', 18 ).where( 'name', '==', 'John' )\n\t * @see whereDeepProp\n\t * @see or\n\t * @see orDeepProp\n\t */\n\twhere<P extends ClassPropNames<T>>( property: P, operator: QueryOperator, value: Partial<T[P]> | Persistent, aggregate?: boolean ) {\n\t\tif ( this.queryObject.operations?.at(-1)?.aggregate && !aggregate ) throw new Error( Model.error.invalidQueryOrder )\n\n\t\tthis.queryObject.operations?.push({\n\t\t\tproperty,\n\t\t\toperator,\n\t\t\tvalue: value as any,\n\t\t\taggregate\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// where2<P extends PropPath<T>>( property: P, operator: QueryOperator, value: PropPathType<T, P> ) {\n\t// \tif ( property.indexOf( '.' ) > 0 ) return this.whereDeepProp( property, operator, value )\n\n\t// \tlet val = value instanceof Persistent? { id: value.id } : value\n\n\t// \tthis.queryObject.operations.push({\n\t// \t\tproperty,\n\t// \t\toperator,\n\t// \t\tvalue: val\n\t// \t})\n\n\t// \treturn this\n\t// }\n\n\t/**\n\t * Matches all documents that the value of the deep property satisfies the condition\n\t * in the operator parameter\n\t * @param propertyPath the path to the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.whereDeepProp( 'address.street', '==', 'Main Street' )\n\t * @see where\n\t * @see or\n\t * @see orDeepProp\n\t */\n\twhereDeepProp( propertyPath: PropPath<T>, operator: QueryOperator, value: PropPathType<T, typeof propertyPath>, aggregate?: boolean ) {\n\t\tif ( this.queryObject.operations?.at(-1)?.aggregate && !aggregate ) throw new Error( Model.error.invalidQueryOrder )\n\n\t\tconst props = ( propertyPath as string ).split( '.' )\n\t\tlet obj = {}\n\t\tlet result = props.length > 1? obj : value // TODO: review\n\n\t\tprops.slice(1).forEach(( prop, i ) => {\n\t\t\tobj[ prop ] = i < props.length - 2? {} : value \n\t\t\tobj = obj[ prop ]\n\t\t})\n\n\t\tthis.queryObject.operations?.push({\n\t\t\tproperty: props[0],\n\t\t\toperator,\n\t\t\tvalue: result,\n\t\t\taggregate\n\t\t} as QueryOperation<T>)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Matches all documents that the value of the property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param property the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.where( 'name', '==', 'John' ).and( 'age', '>', 18 )\n\t * @see andDeepProp\n\t * @see where\n\t * @see whereDeepProp\n\t * @see or\n\t * @see orDeepProp\n\t */\n\tand<P extends ClassPropNames<T>>( property: P, operator: QueryOperator, value: Partial<T[P]> | Persistent ) {\n\t\treturn this.where( property, operator, value )\n\t}\n\n\t/**\n\t * Matches all documents that the value of the deep property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param propertyPath the path to the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.whereDeepProp( 'address.street', '==', 'Main Street' ).andDeepProp( 'address.city', '==', 'New York' )\n\t * @see and\n\t * @see where\n\t * @see whereDeepProp\n\t * @see or\n\t * @see orDeepProp\n\t */\n\tandDeepProp( propertyPath: PropPath<T>, operator: QueryOperator, value: PropPathType<T, typeof propertyPath> ) {\n\t\treturn this.whereDeepProp( propertyPath, operator, value )\n\t}\n\n\t/**\n\t * Matches all documents that the value of the property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param property the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.or( 'name', '==', 'John' )\n\t * query.or( 'age', '>', 18 )\n\t * @see orDeepProp\n\t * @see where\n\t * @see whereDeepProp\n\t */ \n\tor<P extends ClassPropNames<T>>( property: P, operator: QueryOperator, value: Partial<T[P]> | Persistent ) {\n\t\treturn this.where( property, operator, value, true )\n\t}\n\n\t/**\n\t * Matches all documents that the value of the deep property satisfies the condition\n\t * in the operator parameter and aggregates the results to the previous query\n\t * @param propertyPath the path to the property to be compared\n\t * @param operator the operator to be used in the comparison. The available\n\t * operators are: ==, !=, >, >=, < and <=\n\t * @param value the value to be compared\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.orDeepProp( 'address.street', '==', 'Main Street' )\n\t * @see or\n\t * @see where\n\t * @see whereDeepProp\n\t */\n\torDeepProp( propertyPath: PropPath<T>, operator: QueryOperator, value: PropPathType<T, typeof propertyPath> ) {\n\t\treturn this.whereDeepProp( propertyPath, operator, value, true )\n\t}\n\n\t/**\n\t * Defines a where condition to match documents that are instances of the\n\t * given class\n\t * @param classId the class name or an instance to match\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.instanceOf( 'Person' )\n\t * query.instanceOf( Person )\n\t * query.instanceOf( Person ).where( 'age', '>', 18 )\n\t */\n\tinstanceOf<U extends T>( classId: U | string ) {\n\t\tconst className = classId instanceof Persistent? classId.className : classId\n\t\tthis.queryObject.operations?.push({\n\t\t\tproperty: '__className' as any,\n\t\t\toperator: '==',\n\t\t\tvalue: className as any\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Executes the query and returns the result\n\t * @param limit the max amount of documents to retrieve. If not set, uses the\n\t * last limit set or all the matching documents\n\t * @returns a promise resolving to a collection of matched documents\n\t * @example\n\t * const namedJohn = await query.where( 'name', '==', 'John' ).get()\n\t */\n\tget<U extends T>( limit?: number ): Promise<U[]> {\n\t\tif ( limit ) {\n\t\t\tthis.queryObject.limit = limit\n\t\t}\n\t\treturn this.model.query( this.queryObject as unknown as QueryObject<U> )\n\t}\n\n\t/**\n\t * Limits the number of documents to retrieve\n\t * @param maxDocs the max amount of documents to retrieve\n\t * @returns this Query object to make chained calls possible\n\t * @example\n\t * query.where( 'name', '==', 'John' ).limit( 10 )\n\t */\n\tlimit( maxDocs: number ) {\n\t\tthis.queryObject.limit = maxDocs\n\t\treturn this\n\t}\n\n\t/**\n\t * Orders the result set by a property.\n\t * @param propertyName The name of the property to order by\n\t * @param order The sort direction. Possible values are 'asc' and 'desc'\n\t * @returns a chainable query object\n\t * @example\n\t * query.orderBy( 'name', 'asc' )\n\t * query.orderBy( 'age', 'desc' )\n\t */\n\torderBy<P extends ClassPropNames<T>>( propertyName: P, order: QueryOrder = 'asc' ) {\n\t\tthis.queryObject.sort = { \n\t\t\tpropertyName, \n\t\t\torder \n\t\t}\n\t\t\n\t\treturn this\n\t}\n\n\t/**\n\t * Orders the result set by a deep property\n\t * \n\t * @param propertyPath The full path of the deep property. It should be \n\t * \t\t\t\t\t\t\t\t\t\t\tseparated by dots like person.name.firstName.\n\t * @param order The sort direction. Possible values are 'asc' and 'desc'\n\t * @returns a chainable query object\n\t */\n\torderByDeepProp( propertyPath: string, order: QueryOrder = 'asc' ) {\n\t\tthis.queryObject.sort = { \n\t\t\tpropertyName: propertyPath, \n\t\t\torder \n\t\t}\n\t\t\n\t\treturn this\n\t}\n\n\t/**\n\t * Returns the number of documents that match the query\n\t * @returns a promise resolving to the number of documents that match the query\n\t * @example\n\t * const count = await query.where( 'name', '==', 'John' ).count()\n\t */\n\tcount() {\n\t\treturn this.model.count( this.queryObject )\n\t}\n\n\tprivate queryObject: QueryObject<T> = { operations: [] } as QueryObject<T>\n\tprivate model: Model<T>\n}\n","import { DocumentReference, Persistent } from '../persistent/persistent';\nimport { DataSource } from './data-source';\nimport { Model } from './model';\n\n/**\n * The store is the main entry point for the data access layer.\n * It provides methods to retrieve models for collections and subcollections.\n * It also provides methods to populate property references with actual data from the store.\n * You need to register a data source before using the store.\n * @example\n * // Register a data source\n * Store.useDataSource( new FirestoreDataSource( firebase.firestore() ) )\n * // Retrieve a model for a collection\n * const model = Store.getModel( 'User' )\n * // Retrieve a model for a subcollection\n * const model = Store.getModelForSubCollection( user, 'Posts' )\n * // Populate property references\n * const user = await Store.populate( user )\n */\nexport class Store {\n\tprivate constructor(){}\n\n\tstatic error = { shouldBeRegistered: 'You should register a data source before using the data Store.' }\n\n\t/**\n\t * Registers a data source to be used by the store.\n\t * You need to register a data source before using the store.\n\t * @param dataSource the data source to be used by the store\n\t */\n\tstatic useDataSource( dataSource: DataSource ) {\n\t\tthis._dataSource = dataSource\n\t}\n\n\t/**\n\t * The data source currently used by the store\n\t * @returns the data source\n\t */\n\tstatic get dataSource() {\n\t\treturn Store._dataSource\n\t}\n\n\t/**\n\t * Retrieves a model for a collection\n\t * @param classId the class name or an instance of the document type stored in the collection\n\t * @returns the model for the collection\n\t */\n\tstatic getModel< T extends Persistent>( classId: T | string ): Model<T> {\n\t\tif ( !Store._dataSource ) throw new Error( this.error.shouldBeRegistered )\n\t\treturn new Model<T>( Store._dataSource, classId )\t\t\n\t}\n\n\t/**\n\t * Retrieves a model for a subcollection \n\t * @param document the persistent object that owns the subcollection\n\t * @param subCollection the name of the subcollection\n\t * @returns the model for the subcollection\n\t */\n\tstatic getModelForSubCollection< T extends Persistent>( document: Persistent, subCollection: string ): Model<T> {\n\t\tif ( !Store._dataSource ) throw new Error( this.error.shouldBeRegistered )\n\t\treturn new Model<T>( Store._dataSource, document, subCollection )\t\t\n\t}\n\n\t/**\n\t * Populates property references with actual data from the store.\n\t * It will not retrieve data if the instance is already populated\n\t * @param instance the data to be populated.\n\t * @returns the populated instance\n\t */\n\tstatic async populate<T extends Persistent | Persistent[]>( instance: T ): Promise<T> {\n\t\tif ( !instance ) return undefined as any\n\t\t\n\t\tconst populateItem = async ( item: Persistent ) => {\n\t\t\tconst ref: DocumentReference = item as any\n\t\t\tif ( !ref.__documentReference ) return item\n\t\t\tconst model = this.getModel( ref.__documentReference.storedInCollection )\n\n\t\t\tconst populated = await model.findById( ref.id, item ) \n\t\t\tif ( populated ) {\n\t\t\t\tpopulated['__documentReference' ] = undefined\n\t\t\t}\n\t\t\treturn populated\n\t\t}\n\t\t\n\t\tif ( Array.isArray( instance ) ) {\n\t\t\tconst items = await Promise.all(\n\t\t\t\tinstance.map( item => populateItem( item ) )\n\t\t\t)\n\t\t\treturn items.filter( item => item ) as T\n\t\t}\n\t\telse {\n\t\t\treturn populateItem( instance ) as Promise<T>\n\t\t}\n\t}\n\n\t/**\n\t * Checks if an instance is populated\n\t * @param instance the instance or array of instances to be checked\n\t * @returns true if the instance is populated\n\t */\n\tstatic isPopulated< T extends Persistent>( instance: T | readonly T[] ): boolean {\n\t\tif ( Array.isArray( instance ) ) {\n\t\t\treturn instance.reduce(\n\t\t\t\t( prevVal, item ) => prevVal && item['__documentReference'] === undefined,\n\t\t\t\ttrue \n\t\t\t)\n\t\t}\n\t\telse {\n\t\t\treturn instance['__documentReference'] === undefined\n\t\t}\n\t}\n\n\tprivate static _dataSource: DataSource\n}\n","import { Store } from './store'\nimport { Persistent, PersistentObject, Collections, PersistentProperty } from '../persistent/persistent'\nimport { ClassPropNames, Collection } from '../types/utility-types'\n\nexport type DocumentObject = PersistentObject<Persistent>\n\n/**\n * The query operators\n * @param == equal\n * @param != not equal\n * @param < less than\n * @param <= less than or equal\n * @param > greater than\n * @param >= greater than or equal\n * @param contains array contains\n * @param containsAny array contains any\n * @param in in\n * @param !in not in\n */\nexport type QueryOperator = '==' | '!=' | '<' | '<=' | '>' | '>=' | 'contains' | 'containsAny'// | 'in' | '!in'\n\n/**\n * A representation of a query operation\n * @param property the name of the property to be used in the query\n * @param operator the operator to be used in the query\n * @param value the value to be used in the query\n * @param aggregate if true, the query results will be aggregated using an `or` operator\n */\nexport type QueryOperation<T> = {\n\tproperty: ClassPropNames<T>\n\toperator: QueryOperator\n\tvalue: Partial<T[ClassPropNames<T>]> | {[key:string]: unknown}\n\taggregate?: boolean\n}\n\n/**\n * The sort order\n * @param asc ascending order\n * @param desc descending order\n */\nexport type QueryOrder = 'asc' | 'desc'\n\n/**\n * A representation of a full query\n * @param operations the query operations to be performed\n * @param limit the maximum number of items to be retrieved\n * @param sort sort info\n * @param sort.order the sort order\n * @param sort.propertyName the name of the property to be used for sorting\n */\nexport type QueryObject<T> = {\n\toperations?: QueryOperation<T>[]\n\tlimit?: number\n\tsort?: {\n\t\torder: QueryOrder\n\t\tpropertyName: ClassPropNames<T> | string\n\t}\n}\n\nexport type DocumentListenerUninstaller = () => void\n\ninterface DocumentChange {\n\tbefore: Persistent | undefined\n\tafter: Persistent,\n\tparams: { [key: string]: any }\n}\n\nexport type DocumentChangeListerner = ( change: DocumentChange ) => void\nexport interface DocumentChangeListernerHandler {\n\tuninstall: DocumentListenerUninstaller\n\tnativeHandler: unknown\n\tcollectionPath: string\n}\n\ntype CachedPropsUpdateCallback = ( doc: Persistent, prop: PersistentProperty )=>void\n\nexport interface CachedPropsUpdaterConfig {\n\tonUpdate?: CachedPropsUpdateCallback\n\tnoThrowOnNonImplementedListener?: boolean\n\tdocumentChangeListerner?: ( prop: PersistentProperty, listener: DocumentChangeListerner ) => DocumentChangeListernerHandler | undefined\n}\n\ninterface PropWithOwner { \n\tprop: PersistentProperty\n\tcollectionPropOwner: string \n}\n\n/**\n * The data source interface.\n * It defines the methods that must be implemented by a data source\n * A data source is able to retrieve and save data i.e: from a database, a file, a RestAPI, etc.\n * You can derive from this class to implement your own data source with the \n * A data source is used by the store to retrieve and save data.\n */\nexport abstract class DataSource {\n\tinstallCachedPropsUpdaters( config: CachedPropsUpdaterConfig = {} ): DocumentChangeListernerHandler[] {\n\t\tDataSource.onUpdate = config.onUpdate\n\t\tconst referencesWithStoredProps = Persistent.getSystemRegisteredReferencesWithCachedProps()\n\t\tconst collectionsToWatch: Collection<PropWithOwner[]> = {}\n\n\t\tObject.entries( referencesWithStoredProps ).forEach(([ className, props ]) => {\n\t\t\tprops.forEach( propInfo => {\n\t\t\t\tconst collectionName = Persistent.collectionPath( Persistent.createInstance( className ), propInfo )\n\t\t\t\tif ( !collectionsToWatch[ collectionName ] ) collectionsToWatch[ collectionName ] = []\n\t\t\t\tcollectionsToWatch[ collectionName ]!.push({\n\t\t\t\t\tprop: propInfo,\n\t\t\t\t\tcollectionPropOwner: className\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\n\t\tconst handlers: DocumentChangeListernerHandler[] = []\n\t\tObject.entries( collectionsToWatch ).forEach(([ collectionNameToListen, props ]) => {\n\n\t\t\tconst listener = this.subscribeToDocumentChangeListerner( collectionNameToListen, e => DataSource.onDocumentChange( e, props ) )\n\n\t\t\tif ( !listener ) {\n\t\t\t\tif ( config.noThrowOnNonImplementedListener ) throw new Error( `The method documentChangeListerner has not been implemented in the concrete data source` )\n\t\t\t}\n\t\t\telse handlers.push( listener )\n\t\t})\n\n\n\t\t// \tprops.forEach( propInfo => {\n\t\t// \t\tif ( !propInfo.storeInCollection ) return\n\t\t\t\t\t\n\t\t// \t\tlet listenerHandler: DocumentChangeListernerHandler | undefined\n\t\t\t\t\n\t\t// \t\tif ( config.documentChangeListerner ) {\n\t\t// \t\t\tlistenerHandler = config.documentChangeListerner( propInfo, e => this.onDocumentChange( e, propInfo, className ) )\n\t\t// \t\t}\n\t\t// \t\telse {\n\t\t// \t\t\tlistenerHandler = this.subscribeToDocumentChangeListerner( propInfo, e => this.onDocumentChange( e, propInfo, className ) )\n\t\t// \t\t}\n\n\t\t// \t\tif ( !listenerHandler ) {\n\t\t// \t\t\tif ( config.noThrowOnNonImplementedListener ) throw new Error( `The method documentChangeListerner has not been implemented in the concrete data source` )\n\t\t// \t\t}\n\t\t// \t\telse handlers.push( listenerHandler )\n\t\t// \t})\n\t\t// })\n\n\t\treturn handlers\n\t}\n\n\t/**\n\t * Installs a document change listener\n\t * Implement the required logic to install a listener that will be called\n\t * when a document is changed in your concrete the data source\n\t * @param collectionPathToListen the name of the collection to be watched\n\t * @param props the properties to be watched in the collection\n\t * @param listener the listener to be called when a document is changed\n\t * @returns a function that uninstalls the listener. If the returned value is undefined\n\t * the method documentChangeListerner has not been implemented in the concrete data source\n\t */\n\tprotected subscribeToDocumentChangeListerner( collectionPathToListen: string, listener: DocumentChangeListerner ): DocumentChangeListernerHandler | undefined {\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Retrieves a document by id\n\t * Implement the required logic to retrieve a document by id from your concrete\n\t * the data source\n\t * @param id the id of the document to be retrieved\n\t * @param collectionName the name of the collection where the document is stored\n\t * @returns a promise resolving to the document object. The document object is \n\t * a plain object with the properties of the document class.\n\t */\n\tabstract findById( id: string, collectionName: string ): Promise< DocumentObject >\n\n\t/**\n\t * Retrieves all documents matching the query stored in the query object\n\t * Implement the required logic to retrieve the documents that match the \n\t * requirements in the query object from your concrete the data source\n\t * @param queryObject the query object containing the query operations\n\t * @param collectionName the name of the collection where the documents are stored\n\t * @returns a promise resolving to an array of document objects. The document object is\n\t * a plain object with the properties of the document class.\n\t * @see QueryObject\n\t * @see QueryOperation\n\t * @see QueryOperator\n\t * @see QueryOrder\n\t * @see DocumentObject\n\t */\n\tabstract find( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise< DocumentObject[] >\n\n\t/**\n\t * Saves a document\n\t * Implement the required logic to save the document in your concrete the data source\n\t * @param object A collection of documents to be saved\n\t * @returns a promise\n\t */\n\tabstract save( object: Collections ): Promise< void >\n\n\t/**\n\t * Deletes a document by id\n\t * Implement the required logic to delete a document by id from your concrete\n\t * data source\n\t * @param id the id of the document to be deleted\n\t * @param collectionName the name of the collection where the document is stored\n\t * @returns a promise\n\t */\n\tabstract delete( id: string, collectionName: string ): Promise<void>\n\n\t/**\n\t * Retrieves the next bunch of documents matching the query stored in the query object\n\t * Implement the required logic to retrieve the next bunch of documents that match the\n\t * requirements in the query object from your concrete the data source\n\t * @param limit the maximum number of items to be retrieved\n\t * @returns a promise resolving to an array representing the next bunch of document objects\n\t */\n\tabstract next( limit?: number ): Promise< DocumentObject[] >\n\n\t/**\n\t * Retrieves the number of documents matching the query stored in the query object\n\t * Implement the required logic to retrieve the number of documents that match the\n\t * requirements in the query object from your concrete the data source\n\t * @param queryObject the query object containing the query operations\n\t * @param collectionName the name of the collection where the documents are stored\n\t * @returns a promise resolving to the number of documents matching the query\n\t * @see QueryObject\n\t */\n\tabstract count( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise<number>\n\n\t/**\n\t * Utility method to convert a query object to a property path query object\n\t * \n\t * @param queryObject the query object to be converted\n\t * @returns a property path query object\n\t * @example\n\t * const queryObject = {\n\t * \toperations: [{ property: 'name', operator: '==', value: { ancestorName: { father: 'Felipe' }}]\n\t * }\n\t * const propPathQueryObject = DataSource.toPropertyPathQueryObject( queryObject )\n\t * // returned value: [{ property: 'name.ancestorName.father', operator: '==', value: 'Felipe' }]\n\t */\n\tstatic toPropertyPathOperations<T extends Persistent>( operations: QueryOperation<T>[] ): QueryOperation<T>[] {\n\t\tif ( !operations ) return []\n\n\t\treturn operations.map( operation => {\n\n\t\t\tif ( DataSource.isArrayOperator( operation.operator ) && operation.value[0] instanceof Persistent ) {\n\t\t\t\treturn {\n\t\t\t\t\tproperty: Persistent.searchableArrayNameFor( operation.property as string ),\n\t\t\t\t\toperator: operation.operator,\n\t\t\t\t\tvalue: ( operation.value as unknown as Persistent[] ).map( v => v.id ) as any,\n\t\t\t\t\taggregate: operation.aggregate\n\t\t\t\t} as QueryOperation<T>\n\t\t\t}\n\n\t\t\tconst [ path, value ] = this.toPropertyPathValue( operation.value )\n\t\t\tconst propPath = `${ String( operation.property ) }${ path? '.'+path : '' }` \n\n\t\t\treturn { \n\t\t\t\tproperty: propPath, \n\t\t\t\toperator:\toperation.operator,\n\t\t\t\tvalue,\n\t\t\t\taggregate: operation.aggregate\n\t\t\t} as QueryOperation<T>\n\t\t})\n\t}\n\n\tstatic isArrayOperator( operator: QueryOperator ): boolean {\n\t\treturn operator === 'containsAny' || operator === 'contains' //|| operator === 'in' || operator === '!in' \n\t}\n\n\tprivate static toPropertyPathValue( obj: {} ): [ string | undefined, unknown ] {\n\t\tif ( typeof obj === 'object' && !Array.isArray( obj ) ) {\n\t\t\tconst propName = Object.keys( obj )[0]!\n\t\t\tconst [ propPath, value ] = this.toPropertyPathValue( obj[ propName ] )\n\t\t\treturn [ `${ propName }${ propPath? '.'+propPath : '' }`, value ]\n\t\t}\n\t\telse {\n\t\t\treturn [ undefined, obj ]\n\t\t}\n\t}\n\n\tstatic async onDocumentChange( event: DocumentChange, propsToUpdate: PropWithOwner[] ) {\n\t\tif ( !event.before ) return\n\n\t\treturn propsToUpdate.map( async propWithOwner => {\n\n\t\t\tconst model = Store.getModel<any>( propWithOwner.collectionPropOwner )\n\t\t\tlet query = model.find()\n\n\t\t\tpropWithOwner.prop.cachedProps?.forEach( persistentPropName => {\n\t\t\t\tconst oldValue = event.before![ persistentPropName ]\n\t\t\t\tconst newValue = event.after[ persistentPropName ]\n\t\t\t\tif ( oldValue !== newValue ) {\n\t\t\t\t\tquery = query.orDeepProp( `${ propWithOwner.prop.name }.${ persistentPropName }`, '==', oldValue )\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst result = await query.get()\n\t\t\treturn Promise.all([\n\t\t\t\tresult.map( async document =>{\n\t\t\t\t\tpropWithOwner.prop.cachedProps?.forEach( async persistentPropName => {\n\t\t\t\t\t\tconst oldValue = event.before![ persistentPropName ]\n\t\t\t\t\t\tconst newValue = event.after[ persistentPropName ]\n\t\t\t\t\t\tif ( oldValue !== newValue ) {\n\t\t\t\t\t\t\tdocument[ `_${ propWithOwner.prop.name }` ][ `_${ persistentPropName }` ] = newValue\n\t\t\t\t\t\t\tawait model.save( document )\n\t\t\t\t\t\t\tthis.onUpdate?.( document, propWithOwner.prop )\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t])\n\t\t})\n\t}\n\n\tprivate static onUpdate: CachedPropsUpdateCallback | undefined\n}\n","import { Collections, Persistent, PersistentObject } from '../persistent/persistent'\nimport { Collection } from '../types/utility-types'\nimport { DataSource, DocumentChangeListerner, DocumentChangeListernerHandler, DocumentObject, QueryObject, QueryOperation } from \"./data-source\"\n\nexport interface JsonRawData {\n\t[ collection: string ]: {\n\t\t[ documentId: string ]: PersistentObject<Persistent>\n\t}\n}\n\nexport interface ErrorOnOperation {\n\tstore: string\n\tfind: string\n\tfindById: string\n\tdelete: string\n}\n\ntype QueryProcessors = {\n\t[ P in keyof Required<QueryObject<unknown>> ]: Function\n}\n\n/**\n * A concrete implementation of the DataSource interface uses an in-memory data store\n * initialized by a JSON object.\n * It is useful for testing purposes.\n * The data in the JSON object is not persisted.\n */\nexport class JsonDataSource extends DataSource {\n\n\t/**\n\t * @param jsonRawData the JSON object to be used as data store\n\t */\n\tconstructor( jsonRawData?: JsonRawData ) {\n\t\tsuper()\n\t\tif ( jsonRawData ) this._jsonRawData = jsonRawData;\n\t}\n\n\t/**\n\t * Set the JSON object to initialize the data store. Use to set the it after \n\t * the constructor has been called.\n\t * @param jsonRawData the JSON object to be used as data store\n\t */\n\tsetDataStore( rawDataStore: JsonRawData ) {\n\t\tthis._jsonRawData = rawDataStore;\n\t\treturn this\n\t}\n\n\t/**\n\t * Introduce a delay in the execution of operations to simulate a real data source\n\t * @param miliSeconds the number of milliseconds to delay the execution of operations\n\t * @returns a chainable reference to this object\n\t */\n\tsimulateDelay( miliSeconds: number ) {\n\t\tthis._simulateDelay = miliSeconds\n\t\treturn this\n\t}\n\n\tfindById( id: string, collectionName: string ): Promise< DocumentObject > {\n\t\tif ( this._simulateError?.findById ) throw new Error( this._simulateError.findById )\n\n\t\treturn this.resolveWithDelay( this._jsonRawData[ collectionName ]?.[ id ] )\n\t}\n\n\tsave( collections: Collections ): Promise< void > {\n\t\tif ( this._simulateError?.store ) throw new Error( this._simulateError.store )\n\n\t\tObject.entries( collections ).forEach(([ collectionName, collection ]) => {\n\t\t\tif ( !this._jsonRawData[ collectionName ] ) this._jsonRawData[ collectionName ] = {}\n\t\t\tcollection?.forEach( document => {\n\t\t\t\tconst oldValue = this._jsonRawData[ collectionName ]![ document.id ]\n\t\t\t\tthis._jsonRawData[ collectionName ]![ document.id ] = document\n\t\t\t\tif ( oldValue )\t{\n\t\t\t\t\tthis.notifyChange( collectionName, Persistent.createInstance( document ), Persistent.createInstance( oldValue ))\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\t\treturn this.resolveWithDelay()\n\t}\n\n\tfind( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise< DocumentObject[] > {\n\t\tif ( this._simulateError?.find ) throw new Error( this._simulateError.find )\n\n\t\tconst rawDataArray = Object.values( this._jsonRawData[ collectionName ] || {} )\n\t\tif ( !queryObject ) return this.resolveWithDelay( rawDataArray )\n\t\t\n\t\tthis._lastLimit = queryObject.limit || 0\n\t\tthis._cursor = 0\n\n\t\tthis._lastMatchingDocs = Object.entries( queryObject ).reduce(\n\t\t\t( prevDocs, [ processMethod, value ]) => {\n\n\t\t\t\treturn this.queryProcessor( prevDocs, processMethod as any, value )\n\n\t\t\t}, Object.values( rawDataArray )\n\t\t)\n\n\t\treturn this.resolveWithDelay( this._lastMatchingDocs.slice( 0, queryObject.limit ) )\n\t}\n\n\tdelete( id: string, collectionName: string ): Promise<void> {\n\t\tif ( this._simulateError?.delete ) throw new Error( this._simulateError.delete )\n\n\t\tdelete this._jsonRawData[ collectionName ]![ id ]\n\t\treturn this.resolveWithDelay()\n\t}\n\n\tnext( limit?: number ): Promise< DocumentObject[] > {\n\t\tif ( limit ) this._lastLimit = limit\n\t\tthis.incCursor( this._lastLimit )\n\n\t\treturn this.resolveWithDelay( this._lastMatchingDocs.slice( this._cursor, this._cursor + this._lastLimit ) )\n\t}\n\n\tcount( queryObject: QueryObject<DocumentObject>, collectionName: string ): Promise<number> {\n\t\treturn this.resolveWithDelay(\n\t\t\tObject.keys( this._jsonRawData[ collectionName ] ?? {} ).length\n\t\t)\n\t}\n\n\t/**\n\t * @returns the raw data store data as a JSON object\n\t */\n\tget rawData() {\n\t\treturn this._jsonRawData\n\t}\n\n\t/**\n\t * Wait for all pending promises to be resolved\n\t * @returns a promise that resolves when all pending promises are resolved\n\t */\n\twait() {\n\t\treturn Promise.all([ ...this._pendingPromises ])\n\t}\n\n\tprivate incCursor( amount: number ) {\n\t\tthis._cursor += amount \n\t\tif ( this._cursor > this._lastMatchingDocs.length ) {\n\t\t\tthis._cursor = this._lastMatchingDocs.length\n\t\t}\n\t}\n\n\tsimulateError( error: string | ErrorOnOperation | undefined ): this {\n\t\tif ( error === undefined ) {\n\t\t\tthis._simulateError = undefined\n\t\t\treturn this\n\t\t}\n\n\t\tif ( typeof error === 'string' ) {\n\t\t\tthis._simulateError = {\n\t\t\t\tstore: error,\n\t\t\t\tfind: error,\n\t\t\t\tfindById: error,\n\t\t\t\tdelete: error\n\t\t\t}\n\t\t}\n\t\telse this._simulateError = error\n\n\t\treturn this\n\t}\n\n\tprotected override subscribeToDocumentChangeListerner( collectionNameToListen: string, listener: DocumentChangeListerner ): DocumentChangeListernerHandler | undefined {\n\t\tdelete this._listener[ collectionNameToListen ]\n\t\tthis._listener[ collectionNameToListen ] = listener\n\t\treturn {\n\t\t\tuninstall: ()=> delete this._listener[ collectionNameToListen ],\n\t\t\tnativeHandler: listener,\n\t\t\tcollectionPath: collectionNameToListen,\n\t\t}\n\t}\n\n\tprivate notifyChange( collectionPath: string, document: Persistent, oldValue: Persistent | undefined ) {\n\t\tconst listener = this._listener[ collectionPath ]\n\t\tif ( listener ) {\n\t\t\tconst event = {\n\t\t\t\tbefore: oldValue,\n\t\t\t\tafter: document,\n\t\t\t\tcollectionPath\n\t\t\t}\n\t\t\tlistener( event )\n\t\t}\n\t}\n\n\tprivate decCursor( amount: number ) {\n\t\tthis._cursor -= amount \n\t\tif ( this._cursor < 0 ) {\n\t\t\tthis._cursor = 0\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tprivate queryProcessor<T, P extends keyof QueryProcessors>( docs: DocumentObject[], processMethod: P, value: QueryObject<T>[P] ) {\n\n\t\tconst processors: QueryProcessors = {\n\n\t\t\tlimit: ( limit: number ) => docs, //.slice( 0, limit ),\n\n\t\t\toperations: ( operations: QueryOperation<T>[] ) => this.retrieveQueryDocs( docs, operations ),\n\n\t\t\tsort: ({ order, propertyName }) => docs.sort( ( a, b ) => {\n\t\t\t\tif ( order === 'asc' ) {\n\t\t\t\t\treturn this.deepValue( a, propertyName ) > this.deepValue( b, propertyName )? 1 : -1 \n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn this.deepValue( a, propertyName ) < this.deepValue( b, propertyName )? 1 : -1\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\treturn processors[ processMethod ]( value )\n\t}\n\n\tprivate retrieveQueryDocs<T>( docs: DocumentObject[], queryOperations: QueryOperation<T>[] ): DocumentObject[] {\n\t\treturn queryOperations.reduce(( prevDocs, queryOperation, i ) => {\n\t\t\tif ( queryOperation.aggregate ) {\n\t\t\t\tconst aggregate = docs.filter( doc => this.isQueryMatched( doc, queryOperation ) )\n\t\t\t\tif ( i === 0 ) return aggregate\n\t\t\t\telse return prevDocs.concat( aggregate )\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn prevDocs.filter( doc => this.isQueryMatched( doc, queryOperation ) )\n\t\t\t}\n\t\t}, docs )\n\t}\n\n\tprivate deepValue( obj: {}, propertyPath: string /*like person.name.firstName*/) {\n\t\tconst propChain = propertyPath.split( '.' )\n\t\treturn propChain.reduce(( value, prop ) => value[ prop ], obj )\n\t}\n\n\tprivate isQueryMatched<T>( doc: DocumentObject, queryOperation: QueryOperation<T> ) {\n\t\tconst queryOperator = {\n\t\t\t'==': <U>(a: U, b: U) => a === b,\n\t\t\t'!=': <U>(a: U, b: U) => a !== b,\n\t\t\t'<': <U>(a: U, b: U) => a < b,\n\t\t\t'<=': <U>(a: U, b: U) => a <= b,\n\t\t\t'>': <U>(a: U, b: U) => a > b,\n\t\t\t'>=': <U>(a: U, b: U) => a >= b,\n\t\t\t'containsAny': <U>(a: U[], b: U[]) => a?.some( v => b?.includes( v ) ),\n\t\t\t'contains': <U>(a: U[], b: U) => a?.includes( b ),\n\t\t}\n\n\t\tconst { property, value, operator } = queryOperation\n\t\tconst [ propValue, v ] = this.retrieveValuesToCompare( doc, property as string, value )\n\n\t\treturn queryOperator[ operator ]( propValue, v )\n\t}\n\n\tprivate retrieveValuesToCompare( doc: DocumentObject, propertyName: string, value: unknown ): [ any, any ] {\n\t\tconst propertyValue = doc[ propertyName ]\n\n\t\tif ( propertyValue && typeof value === 'object' && !Array.isArray( value )) {\n\t\t\tconst propName = Object.keys( value! )[0]!\n\t\t\tvar [ propVal, val ] = this.retrieveValuesToCompare( propertyValue, propName, value?.[ propName ] )\n\t\t}\n\n\t\treturn [ propVal || propertyValue, val || value ]\n\t}\n\n\tprivate resolveWithDelay<T>( data?: T ): Promise<T> {\n\t\tif ( this._simulateDelay <=0 ) return Promise.resolve( data! )\n\n\t\tconst promise = new Promise<T>( resolve => {\n\t\t\tsetTimeout(\n\t\t\t\t()=> resolve( data! ),\n\t\t\t\tthis._simulateDelay\n\t\t\t)\n\t\t})\n\t\tthis._pendingPromises.push( promise )\n\t\tpromise.finally(\n\t\t\t()=> this._pendingPromises = this._pendingPromises.filter( p => p === promise )\n\t\t)\n\t\treturn promise\n\t}\n\n\tprivate _jsonRawData: JsonRawData = {}\n\tprivate _lastMatchingDocs: DocumentObject[] = []\n\tprivate _lastLimit: number = 0\n\tprivate _cursor: number = 0\n\tprivate _simulateDelay: number = 0\n\tprivate _pendingPromises: Promise<any>[] = []\n\tprivate _simulateError: ErrorOnOperation | undefined\n\tprivate _listener: Collection<DocumentChangeListerner> = {}\n}\n","export type UploadProgress = ( uploadedBytes: number, fileSize: number ) => void\n\ntype CloudStorageFactory = ()=>CloudStorage\n\ninterface CloudStorageFactoryMap { \n\t[ cloudStorageProviderName: string ] : CloudStorageFactory \n}\n\nexport interface UploadControl {\n\tpause: ()=>void\n\tresume: ()=>void\n\tcancel: ()=>void\n\tonProgress: ( callback: UploadProgress )=>void\n}\n\nexport type StorableData = File | Blob | Uint8Array | ArrayBuffer\n\nexport abstract class CloudStorage {\n\tabstract save( id: string, data: StorableData, progress?: UploadProgress ): Promise<string>\n\tabstract getUrl( reference: string ): Promise<string>\n\tabstract uploadControl(): UploadControl\n\tabstract delete( reference: string ): Promise<void>\n\n\tstatic registerCloudStorage( cloudStorageProviderName: string, factory: CloudStorageFactory ) {\n\t\tCloudStorage._cloudStorageFactoryMap[ cloudStorageProviderName ] = factory\n\t}\n\n\tstatic createInstance( providerName: string ) {\n\t\tconst provider = CloudStorage._cloudStorageFactoryMap[ providerName ]\n\t\tif ( !provider ) {\n\t\t\tthrow new Error( `You should register the ${ providerName } cloud storage provider prior to use it`)\n\t\t}\n\n\t\treturn provider()\n\t}\n\n\tget className(): string {\n\t\treturn this[ '__className' ];\n\t}\n\n\tstatic useCloudStorage( provider: CloudStorage ) {\n\t\tCloudStorage._defaultCloudStorage = provider\n\t}\n\n\tstatic get defaultCloudStorage() {\n\t\tif ( !CloudStorage._defaultCloudStorage ) {\n\t\t\tthrow new Error( 'You should define a default cloud storage provider prior to use it')\n\t\t}\n\t\treturn CloudStorage._defaultCloudStorage\n\t}\n\tstatic _defaultCloudStorage: CloudStorage\n\tprivate static _cloudStorageFactoryMap: CloudStorageFactoryMap = {}\n}\n\nexport function registerCloudStorage( cloudStorageProviderName: string, factory: CloudStorageFactory ) {\n\tCloudStorage.registerCloudStorage( cloudStorageProviderName, factory )\n\treturn ( constructor: Function ) => {\n\t\tconstructor.prototype.__className = cloudStorageProviderName\n\t}\n}\n","import { CloudStorage, registerCloudStorage, StorableData, UploadControl, UploadProgress } from './cloud-storage'\n\n@registerCloudStorage( 'MockCloudStorage', ()=>new MockCloudStorage() )\nexport class MockCloudStorage extends CloudStorage {\n\tconstructor( pathToMockFiles: string = '' ) {\n\t\tsuper()\n\t\tthis._pathToMockFiles = pathToMockFiles\n\t}\n\n\t/**\n\t * Introduce a delay in the execution of operations to simulate a real data source\n\t * @param miliSeconds the number of milliseconds to delay the execution of operations\n\t * @returns a chainable reference to this object\n\t */\n\tsimulateDelay( miliSeconds: number ) {\n\t\tthis._simulateDelay = miliSeconds\n\t\treturn this\n\t}\n\n\tprivate resolveWithDelay<T>( data?: T ): Promise<T> {\n\t\tif ( this._simulateDelay <= 0 ) return Promise.resolve( data! )\n\n\t\tconst promise = new Promise<T>( resolve => {\n\t\t\tsetTimeout(\n\t\t\t\t()=> resolve( data! ),\n\t\t\t\tthis._simulateDelay\n\t\t\t)\n\t\t})\n\t\tthis._pendingPromises.push( promise )\n\t\tpromise.finally(\n\t\t\t()=> this._pendingPromises = this._pendingPromises.filter( p => p === promise )\n\t\t)\n\t\treturn promise\n\t}\n\n\tsave( id: string, data: StorableData ): Promise<string> {\n\t\tconst fullPath = id\n\n\t\tif ( this._onProgress ) this._onProgress( 0, 100 )\n\n\t\tthis.mockFileSystem[ id ] = JSON.stringify( data ) \n\n\t\tif ( this._onProgress ) this._onProgress( 100, 100 )\n\n\t\tconst ref = data instanceof File? data.name : fullPath\n\t\treturn this.resolveWithDelay( ref )\n\t}\n\n\tuploadControl(): UploadControl {\n\t\treturn {\n\t\t\tresume: ()=>{},\n\t\t\tpause: ()=>{},\n\t\t\tcancel: ()=>{},\n\t\t\tonProgress: callback => this._onProgress = callback\n\t\t}\n\t}\n\n\tgetUrl( reference: string ): Promise<string> {\n\t\treturn Promise.resolve( this._pathToMockFiles + reference )\n\t}\n\n\tdelete( reference: string ) {\n\t\tdelete this.mockFileSystem[ reference ]\n\t\treturn this.resolveWithDelay<void>()\n\t}\n\n\tprivate _simulateDelay: number = 0\n\tprivate _pendingPromises: Promise<any>[] = []\n\tprivate _onProgress: UploadProgress | undefined\n\tprivate _pathToMockFiles: string\n\tpublic mockFileSystem = {}\n}","import { Callback, Observable } from '../observable/observable'\nimport { persistent, Persistent, registerPersistentClass } from '../persistent/persistent'\nimport { CloudStorage, StorableData, UploadControl, UploadProgress } from './cloud-storage'\n\nexport enum StoredFileEvent { stored, pendingDataSet, deleted }\nexport interface StoredFileChange {\n\tevent: StoredFileEvent\n\tpendingData?: StorableData\n\tstoredFile: StoredFile\n}\n\nexport interface StoreParams {\n\tdata?: StorableData, \n\tfileName?: string, \n\tprogress?: UploadProgress, \n\tcloudStorageProvider?: CloudStorage \n}\n\n@registerPersistentClass( 'StoredFile' )\nexport class StoredFile extends Persistent{\n\n\tasync save({ data, fileName, progress, cloudStorageProvider }: StoreParams = {}): Promise<void> {\n\t\tconst dataToStore = data || this._pendingData\n\t\tif ( !dataToStore ) return\n\t\tif ( this._reference ) await this.delete()\n\n\t\tthis.provider = cloudStorageProvider || CloudStorage.defaultCloudStorage\n\t\tthis._originalFileName = fileName || ( dataToStore instanceof File? dataToStore.name : undefined )\n\n\t\tthis._reference = await this.provider.save( this.id, dataToStore, progress )\n\t\tthis._url = await this.provider.getUrl( this._reference )\n\n\t\tthis._pendingData = undefined\n\t\tthis._onChange.notify({ event: StoredFileEvent.stored, storedFile: this })\n\t}\n\n\tuploadControl(): UploadControl {\n\t\treturn this.provider.uploadControl()\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tif ( !this._reference ) throw new Error( 'Cannot delete a not stored file' )\n\t\tawait this.provider.delete( this._reference )\n\t\tthis._reference = undefined\n\t\tthis._url = undefined\n\t\tthis._onChange.notify({ event: StoredFileEvent.deleted, storedFile: this })\n\t}\n\n\tset provider( value: CloudStorage ) {\n\t\tthis._provider = value\n\t\tthis._cloudStorageProviderName = value.className\n\t}\n\n\tget provider() {\n\t\tif ( !this._provider ) {\n\t\t\ttry {\n\t\t\t\tthis._provider = CloudStorage.createInstance( this._cloudStorageProviderName! )\n\t\t\t} \n\t\t\tcatch {\n\t\t\t\tthis._provider = CloudStorage.defaultCloudStorage\n\t\t\t}\n \t\t}\n\t\treturn this._provider\n\t}\n\n\tget url() {\n\t\treturn this._url\n\t}\n\n\tget mimeType() {\n\t\treturn this._mimeType\n\t}\n\n\tsetDataToStore( data: StorableData ) {\n\t\tthis._pendingData = data\n\t\tthis._originalFileName = data instanceof File? data.name : undefined\n\t\tthis._mimeType = data instanceof Blob? data.type : undefined\n\t\tthis._onChange.notify({ \n\t\t\tevent: StoredFileEvent.pendingDataSet, \n\t\t\tpendingData: data,\n\t\t\tstoredFile: this \n\t\t})\n\t\treturn this\n\t}\n\n\tget originalFileName() {\n\t\treturn this._originalFileName\n\t}\n\n\tonChange( listenerCallback: Callback<StoredFileChange> ) {\n\t\treturn this._onChange.subscribe( listenerCallback )\n\t}\n\n\t@persistent private _reference: string | undefined\n\t@persistent private _url: string | undefined\n\t@persistent private _cloudStorageProviderName: string | undefined\n\t@persistent private _originalFileName: string | undefined\n\t@persistent private _mimeType: string | undefined\n\tprivate _provider: CloudStorage | undefined\n\tprivate _pendingData: StorableData | undefined\n\tprivate _onChange: Observable<StoredFileChange> = new Observable<StoredFileChange>()\n}\n","import { Observable } from '../observable/observable'\nimport { AuthProvider, SignData, UserCredentials } from \"./user-auth-types\"\n\n/**\n * The AuthService class is an abstract class that defines the interface of an authentication service.\n * You should derive from this class to implement your own authentication service.\n */\nexport abstract class AuthService {\n\tabstract signUp<T extends {}>( signData: SignData ): Promise<UserCredentials<T>>\n\tabstract login<T extends {}>( signData: SignData ): Promise<UserCredentials<T>>\n\tabstract logout(): Promise<void>\n\tabstract resetEmailPassword( email: string ): Promise<void>\n\tabstract refreshToken(): Promise<void>\n\tabstract linkAdditionalProvider( provider: AuthProvider ): Promise<unknown>\n\tabstract unlinkProvider( provider: AuthProvider ): Promise<unknown>\n\tabstract onAuthStateChange<T extends {}>( onChange: (userCredentials: UserCredentials<T> | undefined) => void ): void\n\tabstract resendVerificationEmail( email: string, password: string, verificationLink: string ): Promise<void>\n}\n\nexport type AuthErrorCode = 'wrongPassword' | 'popupClosedByUser' | 'userNotFound' | 'invalidEmail' | 'missingPassword' | 'missingEmail'\n\nexport interface AuthError {\n\tcode: AuthErrorCode\n\tmessage: string\n}\n\n/**\n * Types the callback to accept a user credentials object\n */\nexport type ResovedCallback<T extends {}> = ( credentials: UserCredentials<T> ) => void\nexport type RejectedCallback = ( reason: AuthError ) => void\n\n/**\n * The Auth class is a singleton that provides a unified interface to the authentication service.\n * You should register an authentication service by using `Auth.useAuthService` \n * method before using the Auth class.\n */\nexport class Auth extends AuthService {\n\tstatic error = { shouldBeRegistered: 'You should register an auth service before using Auth.' }\n\n\tprotected constructor() {\n\t\tsuper()\n\t\tif (!Auth._authService ) throw ( new Error( Auth.error.shouldBeRegistered ) )\n\t\tAuth._authService.onAuthStateChange( \n\t\t\tuserCredentials => this.authStateChanged( userCredentials ) \n\t\t)\n\t}\n\n\t/**\n\t * Registers an authentication service to be used by the Auth class.\n\t * You need to register an authentication service before using the Auth class.\n\t * @param authService the authentication service to be used by the Auth class\n\t */\n\tstatic useAuthService( authService: AuthService ) {\n\t\tif ( Auth._authService != authService ) {\n\t\t\tAuth._authService = authService\n\t\t\tthis._instance = undefined\n\t\t}\n\t}\n\n\t/**\n\t * The instance of the Auth class\n\t * @returns the authentication service\n\t */\n\tstatic get instance() {\n\t\treturn this._instance || (this._instance = new this() )\n\t}\n\n\t/**\n\t * Signs up a new user\n\t * @param singData the data to be used to sign up the user\n\t * @returns a promise that resolves to the user credentials\n\t * @example\n\t * // Sign up a new user with email and password\n\t * Auth.instance.signUp({ authProvider: 'email', email: 'john@test.com', password: '123456' })\n\t * // Sign up a new user with a Google account\n\t * Auth.instance.signUp({ authProvider: 'google'})\n\t */\n\tsignUp<T extends {}>( singData: SignData ): Promise<UserCredentials<T>> {\n\t\treturn Auth._authService.signUp( singData )\n\t}\n\n\t/**\n\t * Logs in an existing user\n\t * @param singData the data to be used to log in the user\n\t * @returns a promise that resolves to the user credentials\n\t * @example\n\t * // Log in an existing user with email and password\n\t * Auth.instance.login({ authProvider: 'email', email: 'john@test.com', password: '123456' })\n\t * // Log in an existing user with a Google account\n\t * Auth.instance.login({ authProvider: 'google'})\n\t */\n\tlogin<T extends {}>( singData: SignData ): Promise<UserCredentials<T>> {\n\t\treturn Auth._authService.login( singData )\n\t}\n\t\n\t/**\n\t * Logs out the current user\n\t * @returns a promise that resolves when the user is logged out\n\t */\n\tlogout(): Promise<void> {\n\t\treturn Auth._authService.logout()\n\t}\n\n\t/**\n\t * Resets the password associated with the email.\n\t * @param email the email address of the user to reset the password\n\t * @returns a promise that resolves when the process is done\n\t */\n\tresetEmailPassword( email: string ) {\n\t\treturn Auth._authService.resetEmailPassword( email )\n\t}\n\n\t/**\n\t * Resends the email verification to the user.\n\t * @returns a promise that resolves when the process is done\n\t */\n\toverride resendVerificationEmail( email: string, password: string, verificationLink: string ): Promise<void> {\n\t\treturn Auth._authService.resendVerificationEmail( email, password, verificationLink )\n\t}\n\n\toverride refreshToken(): Promise<void> {\n\t\treturn Auth._authService.refreshToken()\n\t}\n\n\t/**\n\t * Adds a listener to be called when the authentication state changes.\n\t * @param onChange the listener to be called when the authentication state changes.\n\t * The listener is called with the user credentials as a parameter.\n\t * If the user is logged out, the listener is called with `undefined` as a parameter.\n\t * @returns a function to remove the listener\n\t * @example\n\t * // Add a listener to be called when the authentication state changes\n\t * const removeListener = Auth.instance.onAuthStateChange( userCredentials => {\n\t * \tif ( userCredentials ) {\n\t * \t\t// The user is logged in\n\t * \t} else {\n\t * \t\t// The user is logged out\n\t * \t}\n\t * })\n\t */\n\tonAuthStateChange<T extends {}>( onChange: ( userCredentials: UserCredentials<T> )=>void ) {\n\t\treturn this._onAuthStateChange.subscribe( onChange )\n\t}\n\n\t/**\n\t * Removes a listener that was added by `onAuthStateChange` method.\n\t * @param onChange the listener to be removed\n\t */\n\tremoveAuthStateChange<T extends {}>( onChange: ( userCredentials: UserCredentials<T> )=>void ) {\n\t\tthis._onAuthStateChange.unsubscribe( onChange )\n\t}\n\n\t/**\n\t * Links an additional authentication provider to the authenticated user.\n\t * @param provider the provider to be linked\n\t * @returns a promise that resolves when the process is done\n\t * @example\n\t * // Link a Google account to the auth service\n\t * Auth.instance.linkAdditionalProvider({ authProvider: 'google' })\n\t */\n\tlinkAdditionalProvider( provider: AuthProvider ): Promise<unknown> {\n\t\treturn Auth._authService.linkAdditionalProvider( provider )\n\t}\n\n\t/**\n\t * Unlinks an authentication provider from the authenticated user.\n\t * @param provider the provider to be unlinked\n\t * @returns a promise that resolves when the process is done\n\t * @example\n\t * // Unlink the Google account from the auth service\n\t * Auth.instance.unlinkProvider({ authProvider: 'google' })\n\t */\n\tunlinkProvider( provider: AuthProvider ): Promise<unknown> {\n\t\treturn Auth._authService.unlinkProvider( provider )\n\t}\n\n\tprivate authStateChanged( userCredentials: UserCredentials<{}> | undefined ) {\n\t\tthis._onAuthStateChange.notify( userCredentials )\n\t}\n\n\tprivate static _instance: Auth | undefined = undefined\n\tprivate static _authService: AuthService\n\tprivate _onAuthStateChange: Observable<UserCredentials<{}>> = new Observable<UserCredentials<{}>>()\n}","import { Collection } from '../types/utility-types'\nimport { AuthService, RejectedCallback, ResovedCallback } from \"./auth\"\nimport { UserCredentials, SignData, AuthProvider } from \"./user-auth-types\"\n\nexport class AuthMock extends AuthService {\n\n\tsignUp<T extends {}>( signData: SignData ): Promise<UserCredentials<T>> {\n\t\tconst { verificationLink, email, password, authProvider } = signData\n\t\n\t\tconst promise = new Promise<UserCredentials<T>>( async ( resolve: ResovedCallback<T>, reject: RejectedCallback ) => {\n\t\t\tif ( authProvider === 'email' ) {\n\t\t\t\tif ( !email ) reject({ code: 'missingEmail', message: 'missingEmail' })\n\t\t\t\tif ( !password ) reject({ code: 'missingPassword', message: 'missingPassword' })\n\t\t\t}\n\t\t\tif ( password !== 'fail' && email !== 'fail' ) {\n\t\t\t\tthis._loggedUser = this.userCredentials<T>( signData )\n\t\t\t\tthis._fakeRegisteredUsers[ this._loggedUser.id ] = this._loggedUser \n\t\t\t\tresolve( this._loggedUser as UserCredentials<T> )\n\t\t\t\tthis.notifyChange?.( this._loggedUser )\n\t\t\t} \n\t\t\telse {\n\t\t\t\treject({ code: 'userNotFound', message: verificationLink || 'Test auth error' })\n\t\t\t\tthis.notifyChange?.( undefined )\n\t\t\t}\n\t\t})\n\t\tthis.pendingPromises.push( promise )\n\t\treturn promise\n\t}\n\n\tlogin<T extends {}>( signData: SignData ): Promise<UserCredentials<T>> {\n\t\tconst fakeUser = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === signData.email \n\t\t)\n\n\t\tif ( signData.authProvider === 'email' && !fakeUser && signData.email) {\n\t\t\tsignData.email = 'fail'\n\t\t}\n\n\t\treturn this.signUp( signData )\n\t}\n\n\tonAuthStateChange<T extends {}>( onChange: ( userCredentials: UserCredentials<T> )=>void ) {\n\t\tthis.notifyChange = onChange\n\t\tthis.notifyChange( this._loggedUser )\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tconst promise = new Promise<void>( resolve => {\n\t\t\tthis._loggedUser = undefined\n\t\t\tresolve() \n\t\t\tthis.notifyChange?.( undefined )\n\t\t})\n\t\tthis.pendingPromises.push( promise )\n\t\treturn promise\n\t}\n\n\tresetEmailPassword( email: string ) {\n\t\tconst fakeUserExists = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === email \n\t\t)\n\n\t\tif ( fakeUserExists ) return Promise.resolve()\n\t\telse return Promise.reject({ code: 'userNotFound', message: 'Test auth error' })\n\t}\n\n\tresendVerificationEmail( email: string, _password: string, _verificationLink: string ) {\n\t\tconst fakeUserExists = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === email \n\t\t)\n\n\t\tif ( fakeUserExists ) return Promise.resolve()\n\t\telse return Promise.reject({ code: 'userNotFound', message: 'Test auth error' })\n\t}\n\n\toverride refreshToken(): Promise<void> {\n\t\treturn Promise.resolve()\n\t}\n\n\tlinkAdditionalProvider( provider: AuthProvider ): Promise<unknown> {\n\t\tthrow new Error('Not implemented.')\n\t}\n\t\n\tunlinkProvider( provider: AuthProvider ): Promise<unknown> {\n\t\tthrow new Error('Not implemented.')\n\t}\n\t\n\tasync flush() {\n\t\tawait Promise.all(this.pendingPromises)\n this.pendingPromises = []\n\t}\n\n\tfakeRegisteredUser<T extends {}>( userCredentials: UserCredentials<T> ) {\n\t\tif ( this._fakeRegisteredUsers[ userCredentials.id ] ) throw new Error( `User with id ${ userCredentials.id } already exists in fake user list`)\n\t\tthis._fakeRegisteredUsers[ userCredentials.id ] = userCredentials\n\t\treturn this\n\t}\n\n\tget fakeRegisteredUsers() {\n\t\treturn this._fakeRegisteredUsers\n\t}\n\n\tprivate userCredentials<T extends {}>( signData: SignData ): UserCredentials<T> {\n\t\tconst fakeUser = Object.values( this._fakeRegisteredUsers ).find( \n\t\t\tuser => user.email === signData.email \n\t\t)\n\t\t\n\t\tif ( fakeUser ) {\n\t\t\treturn { ...fakeUser as UserCredentials<T> }\n\t\t}\n\t\telse {\n\t\t\treturn ({\n\t\t\t\tid: signData.authProvider || `testUID${ signData.email? '-' + signData.email : '' }`,\n\t\t\t\temail: signData.email || 'testEmail',\n\t\t\t\tname: signData.authProvider || `testName${ signData.email? ' ' + signData.email : '' }` ,\n\t\t\t\tphoneNumber: 'testPhone',\n\t\t\t\tcustomData: {\n\t\t\t\t\trole: 'test'\n\t\t\t\t} as unknown as T,\n\t\t\t\tlastLogin: 0,\n\t\t\t\tcreationDate: 0\n\t\t\t} as UserCredentials<T>)\n\t\t}\n\t}\n\n\tprivate pendingPromises: Promise<any>[] = []\n\tprivate _loggedUser: UserCredentials<{}> | undefined\n\tprivate notifyChange: (( userCredentials: UserCredentials<{}> | undefined ) => void ) | undefined\n\tprivate _fakeRegisteredUsers: Collection<UserCredentials<{}>> = {}\n}","import { Persistent, PersistentObject } from '../persistent/persistent'\n\n\nexport type CloudFunction<P,R> = ( param?: P) => Promise<R>\n\nexport interface CloudFunctionsService {\n\tretrieveFunction<P, R>( cloudFunction: string ): CloudFunction<P, R>\n\tcallFunction<P,R>( func: CloudFunction<P, R>, params: P ): Promise<R>\n}\n\nexport class CloudFunctions {\n\tprivate constructor() {}\n\n\tstatic error = { shouldBeRegistered: 'You should register a cloud functions service with useCloudFunctionsService static method before using CloudFunctions.' }\n\n\tstatic useCloudFunctionsService( cloudFunctionsService: CloudFunctionsService ) {\n\t\tif ( this._cloudFunctionsService != cloudFunctionsService ) {\n\t\t\tthis._cloudFunctionsService = cloudFunctionsService\n\t\t}\n\t}\n\n\tstatic get instance() {\n\t\tif ( !this._cloudFunctionsService ) throw new Error( CloudFunctions.error.shouldBeRegistered )\n\t\treturn CloudFunctions._instance || ( CloudFunctions._instance = new CloudFunctions() )\n\t}\n\n\tgetRawFunction<P, R>( cloudFunction: string ): CloudFunction<P,R> {\n\t\treturn CloudFunctions._cloudFunctionsService.retrieveFunction( cloudFunction )\n\t}\n\n\tgetFunction<P, R=void>( cloudFunction: string ): CloudFunction<P,R> {\n\t\tconst callFunction = CloudFunctions._cloudFunctionsService.callFunction\n\t\tconst func = this.getRawFunction<P, R>( cloudFunction )\n\n\t\treturn async ( param: P ) => {\n\t\t\tconst result = await callFunction( func, this.processParam( param ) )\n\t\t\treturn this.processResult( result )\n\t\t}\n\t}\n\n\tprivate processParam<P>( param: P ): P | PersistentObject<P & Persistent> {\n\t\tif ( param === undefined || param === null ) return undefined!\n\n\t\tif ( param instanceof Persistent ) return param.toObject()\n\n\t\tif ( Array.isArray( param ) ) {\n\t\t\treturn param.map( p => this.processParam( p ) ) as unknown as P\n\t\t}\n\n\t\tif ( typeof param === 'object' ) {\n\t\t\treturn Object.entries( param ).reduce(( newParam, [ key, value ])=>{\n\t\t\t\tnewParam[ key ] = this.processParam( value )\n\t\t\t\treturn newParam\n\t\t\t}, {}) as P\n\t\t}\n\n\t\treturn param\n\t}\n\n\tprivate processResult<R>( value: R | PersistentObject<R & Persistent> ): R {\n\t\tif ( value === undefined || value === null ) return undefined!\n\n\t\tif ( ( value as PersistentObject<R & Persistent> ).__className ) {\n\t\t\treturn Persistent.createInstance( value as PersistentObject<R & Persistent> ) as R\n\t\t}\n\n\t\tif ( Array.isArray( value ) ) {\n\t\t\treturn value.map( elem => this.processResult( elem ) ) as unknown as R\n\t\t}\n\n\t\tif ( typeof value === 'object' ) {\n\t\t\treturn Object.entries( value ).reduce((newVal, [ key, val ]) => {\n\t\t\t\tnewVal[ key ] = this.processResult( val )\n\t\t\t\treturn newVal\n\t\t\t}, {}) as R\n\t\t}\n\n\t\treturn value as R\n\t}\n\n\tprivate static _cloudFunctionsService: CloudFunctionsService\n\tprivate static _instance: CloudFunctions\n}","import { CloudFunction, CloudFunctionsService } from './cloud-functions'\n\ninterface FunctionCollection { \n\t[key: string]: CloudFunction<any,any>\n}\n\nexport class CloudFunctionsMock implements CloudFunctionsService {\n\tconstructor( registeredFunctions: FunctionCollection ) {\n\t\tthis._registeredFunctions = registeredFunctions\n\t}\n\n\tretrieveFunction<P, R>( cloudFunction: string ): CloudFunction<P,R> {\n\t\tconst func = this._registeredFunctions[ cloudFunction ]\n\t\tif ( !func ) throw new Error( `Cloud function ${ cloudFunction } is not registered.` )\n\t\treturn func\n\t}\n\n\tcallFunction<P, R>( func: CloudFunction<P, R>, params: P ): Promise<R> {\n\t\treturn func( params )\n\t}\n\n\tprivate _registeredFunctions: FunctionCollection\n}","import { UserCredentials } from '../auth/user-auth-types'\n\nexport interface CustomCredentials {\n\t[ key: string ]: unknown\n}\n\nexport abstract class ServerAuthService {\n\tabstract setCustomCredentials<T extends CustomCredentials>( userId: string, customCredentials: T ): Promise<void>\n\tabstract getUser<T extends CustomCredentials>( userId: string ): Promise<UserCredentials<T> | undefined>\n\tabstract updateUser<T extends CustomCredentials>( userId: string, credentials: Partial<UserCredentials<T>> ): Promise<UserCredentials<T>>\n\tabstract deleteUser( userId: string ): Promise<void>\n}\n\nexport class ServerAuth extends ServerAuthService {\n\tstatic error = { shouldBeRegistered: 'You should register a Server Auth service before using the Server Auth.' }\n\n\tprotected constructor(){ super() }\n\n\tstatic useServerAuthService( authService: ServerAuthService ) {\n\t\tif ( ServerAuth._authService != authService ) {\n\t\t\tServerAuth._authService = authService\n\t\t\tthis._instance = undefined\n\t\t}\n\t}\n\n\tstatic get instance() {\n\t\tif ( !ServerAuth._authService ) throw new Error( ServerAuth.error.shouldBeRegistered )\n\t\treturn this._instance || (this._instance = new ServerAuth() )\n\t}\n\t\n\tgetUser<T extends CustomCredentials>( userId: string ): Promise<UserCredentials<T> | undefined> {\n\t\treturn ServerAuth._authService.getUser( userId )\n\t}\n\n\tupdateUser<T extends CustomCredentials>( userId: string, credentials: Partial<UserCredentials<T>> ): Promise<UserCredentials<T>> {\n\t\treturn ServerAuth._authService.updateUser( userId, credentials )\n\t}\n\t\n\tsetCustomCredentials<T extends CustomCredentials>( userId: string, customCredentials: T ): Promise<void> {\n\t\treturn ServerAuth._authService.setCustomCredentials( userId, customCredentials )\n\t}\n\n\tdeleteUser( userId: string ) {\n\t\treturn ServerAuth._authService.deleteUser( userId )\n\t}\n\n\tprivate static _instance: ServerAuth | undefined = undefined\n\tprivate static _authService: ServerAuthService\n}","import { UserCredentials } from '../auth/user-auth-types'\nimport { Collection } from '../types/utility-types'\nimport { ServerAuthService, CustomCredentials } from './server-auth'\n\nexport class ServerAuthMock extends ServerAuthService {\n\tconstructor( userCredentials: Collection<UserCredentials<{}>> ) {\n\t\tsuper()\n\t\tthis._userCredentials = userCredentials\n\t}\n\n\tgetUser<T extends CustomCredentials>( userId: string ): Promise<UserCredentials<T> | undefined> {\n\t\tif ( !this._userCredentials[ userId ] ) Promise.resolve( undefined )\n\n\t\treturn Promise.resolve( this._userCredentials[ userId ] as UserCredentials<T> )\n\t}\n\n\tsetCustomCredentials<T extends CustomCredentials>( userId: string, customCredentials: T ): Promise<void> {\n\t\tconst userCredentials = this._userCredentials[ userId ]\n\t\tif ( !userCredentials ) throw new Error( `User ${ userId } not found in the auth system` )\n\t\tuserCredentials.customData = { ...customCredentials }\n\n\t\treturn Promise.resolve()\n\t}\n\n\tupdateUser<T extends CustomCredentials>( userId: string, credentials: Partial<UserCredentials<T>> ): Promise<UserCredentials<T>> {\n\t\tthis._userCredentials[ userId ] = {\n\t\t\t...this._userCredentials,\n\t\t\t...credentials,\n\t\t\tid: userId\n\t\t} as UserCredentials<T>\n\n\t\treturn Promise.resolve( this._userCredentials[ userId ] as UserCredentials<T> )\n\t}\n\n\tdeleteUser( userId: string ): Promise<void> {\n\t\tdelete this._userCredentials[ userId ]\n\t\treturn Promise.resolve()\n\t}\n\n\tget userCredentials() {\n\t\treturn this._userCredentials\n\t}\n\n\tprivate _userCredentials: Collection<UserCredentials<{}>>\n}\n","import { PropPath, PropPathType } from '../types/utility-types'\n\n/**\n * A map of key-value pairs\n * @param varName the name of the variable\n * @param value the value of the variable\n */\nexport interface Values {\n\t[ varName: string ]: string;\n}\n\n/**\n * Replaces keys found in a string for its values. The keys should be inserted \n * inside brackets ${ key } as is done in the string template literals substitutions\n * @param text the string template\n * @param values an object with key-value pairs\n * @returns the string filled with corresponding values\n * @example\n * const text = 'Hello ${name}, how are you ${ action }?'\n * const values = { name: 'John', action: 'today' }\n * const result = replaceValue( text, values )\n * // result = 'Hello John, how are you today?'\n */\nexport function replaceValue( text: string | undefined | null, values: Values ): string {\n\tif ( !text ) return ''\n\t\n\treturn text.replace(/\\${\\s*(\\w*)\\s*}/g, function( _match , group){\n\t\treturn values[ group ] || '';\n\t});\n}\n\n/**\n * Transforms a string to a camel case format (camelCaseFormat)\n * @param str the string to transform. It can be a string with spaces or a \n * snake case format\n * @returns the camel case transformed string\n * @example\n * const str = 'snake-case-format'\n * const result = camelCase( str )\n * // result = 'snakeCaseFormat'\n */\nexport function camelCase( str: string | undefined | null ) {\n\tif ( !str ) return ''\n\n\treturn str.replace(\n\t\t/([-_ ][\\w])/g,\n\t\tgroup => group.toUpperCase().replace('-', '').replace('_', '').replace(' ', '')\n\t)\n}\n\n/**\n * Transforms a string in to a snake case format (snake-case-format)\n * @param str the string to transform. It can be a string with spaces or a camel\n * case format\n * @param snakeChar the character used to separate words. If the passed string is\n * in camel case and the snakeChar is a space, this will transform the came case\n * string in to a regular spaced string\n * @returns the snake case transformed string\n * @example\n * const str = 'camelCaseFormat'\n * const result = snakeCase( str )\n * // result = 'camel-case-format'\n */\nexport function snakeCase( str: string | undefined | null, snakeChar: string = '-' ) {\n\tif ( !str ) return ''\n\tconst replaced = str.slice(1).replace(/( |[A-Z])/g, g => g===' '? '-' : snakeChar + g[0]!.toLowerCase() )\n\treturn str[0]!.toLocaleLowerCase() + replaced.replace(/--/g, '-')\n}\n\n/**\n * Gets the value of the supproperty in the passed object\n * \n * @param obj the object containing the subproperty \n * @param path a string containing the subproperty path in dotted notation\n * @returns the value of the supproperty in the passed object\n * @example\n * const obj = { a: { b: { c: 1 } } }\n * const path = 'a.b.c'\n * const result = getDeepValue( obj, path )\n * // result = 1\n */\nexport function getDeepValue<T extends {}, P extends PropPath<T> & string>( obj: T, path: P ): PropPathType<T, P> {\n\treturn ( path as string ).split('.').reduce(( acc: {}, prop: string ) => acc[ prop ], obj )\n}\n"],"names":["Observable","callback","event","subs","byteToHex","i","unsafeStringify","arr","offset","getRandomValues","rnds8","rng","randomUUID","native","v4","options","buf","rnds","_a","_Persistent","className","factory","annotation","derivedFrom","obj","id","uuid","value","prop","propName","propInfo","validator","instance","rootCollections","propValue","item","ref","emptyInstance","newObject","key","val","ownerInstance","storeInCollection","cachedProps","forcedObject","collections","collectionName","document","e","stringifiedObj","_key","registeredClassName","referencesWithStoredProps","propsWithStoredValue","__decorateClass","persistent","Persistent","target","property","persistentParser","persistentReferenceAt","collectionPath","persistentReference","persistentReferenceWithCachedProps","propTypeName","persistentPureReference","persistentPureReferenceWithCachedProps","registerPersistentClass","constructor","registerLegacyClassName","legacyName","searchableArray","required","requiredWithValidator","EntropicComponent","listenerCallback","pName","arrayPropName","element","isUnique","isEqual","originalLength","_Model","stream","persistentClass","subCollection","resolve","reject","data","error","Query","queryObject","objectType","limit","from","operations","operation","DataSource","v","Model","model","operator","aggregate","_b","_c","propertyPath","props","result","classId","maxDocs","propertyName","order","_Store","dataSource","populateItem","populated","prevVal","Store","config","collectionsToWatch","handlers","collectionNameToListen","listener","collectionPathToListen","path","propPath","propsToUpdate","propWithOwner","query","persistentPropName","oldValue","newValue","JsonDataSource","jsonRawData","rawDataStore","miliSeconds","collection","rawDataArray","prevDocs","processMethod","amount","docs","a","b","queryOperations","queryOperation","doc","queryOperator","propertyValue","propVal","promise","p","_CloudStorage","cloudStorageProviderName","providerName","provider","CloudStorage","registerCloudStorage","MockCloudStorage","pathToMockFiles","fullPath","reference","StoredFileEvent","StoredFileEvent2","StoredFile","fileName","progress","cloudStorageProvider","dataToStore","AuthService","_Auth","userCredentials","authService","singData","email","password","verificationLink","onChange","Auth","AuthMock","signData","authProvider","fakeUser","user","_password","_verificationLink","_CloudFunctions","cloudFunctionsService","cloudFunction","callFunction","func","param","newParam","elem","newVal","CloudFunctions","CloudFunctionsMock","registeredFunctions","params","ServerAuthService","_ServerAuth","userId","credentials","customCredentials","ServerAuth","ServerAuthMock","replaceValue","text","values","_match","group","camelCase","str","snakeCase","snakeChar","replaced","g","getDeepValue","acc"],"mappings":"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","x_google_ignoreList":[1,2,3,4]}