import { Injectable } from "@angular/core" ; import { Database } from "../database/database" ; import { Entity , EntityConstructor } from "./model/entity" ; import { EntitySchemaService } from "./schema/entity-schema.service" ; import { Observable , Subject } from "rxjs" ; import { UpdatedEntity } from "./model/entity-update" ; /**
 * Handles loading and saving of data for any higher-level feature module.
 * The EntityMapperService implicitly transforms objects from instances of Entity classes to the format to be written
 * to the database and back - ensuring they you always receive instances of  Entity subclasses, that you can
 * simply treat them as normal javascript class instances without worrying about database persistance logic.
 *
 * To understand more about how to use the Entity system in your own modules, refer to the How-To Guides:
 * - [How to Load and Save Data] {@link /additional-documentation/how-to-guides/load-and-save-data.html} * - [How to Create a new Entity Type] {@link /additional-documentation/how-to-guides/create-a-new-entity-type.html} @ Injectable ( ) export class EntityMapperService { private publishers : Map < string , Subject < any > > = new Map ( ) ; constructor ( private _db , private entitySchemaService ) { } param entityType param id returns public async load < T extends Entity > ( entityType , id ) { const resultEntity = new entityType ( "" ) ; const result = await this . _db . get ( Entity . createPrefixedId ( resultEntity . getType ( ) , id ) ) ; this . entitySchemaService . loadDataIntoEntity ( resultEntity , result ) ; return resultEntity ; } param entityType returns public async loadType < T extends Entity > ( entityType ) { const resultArray = [ ] ; const allRecordsOfType = await this . _db . getAll ( new entityType ( "" ) . getType ( ) + ":" ) ; for ( const record of allRecordsOfType ) { const entity = new entityType ( "" ) ; this . entitySchemaService . loadDataIntoEntity ( entity , record ) ; resultArray . push ( entity ) ; } return resultArray ; } param entityType public receiveUpdates < T extends Entity > ( entityType ) { const type = new entityType ( ) . getType ( ) ; let publisher = this . publishers [ type ] ; if ( ! publisher || publisher . closed ) { publisher = new Subject < T > ( ) ; this . publishers [ type ] = publisher ; } return publisher . asObservable ( ) ; } param entity param forceUpdate public async save < T extends Entity > ( entity , forceUpdate = false ) { const rawData = this . entitySchemaService . transformEntityToDatabaseFormat ( entity ) ; this . sendUpdate ( entity , entity . _rev === undefined ? "new" : "update" ) ; const result = await this . _db . put ( rawData , forceUpdate ) ; if ( result ?. ok ) { entity . _rev = result . rev ; } return result ; } param entity public remove < T extends Entity > ( entity ) { this . sendUpdate ( entity , "remove" ) ; return this . _db . remove ( entity ) ; } param entity param type The type, see  UpdatedEntity private sendUpdate < T extends Entity > ( entity , type ) { const publisher = this . publishers [ entity . getType ( ) ] ; if ( publisher && ! publisher . closed ) { publisher . next ( { entity : entity , type : type } ) ; } } }