/**
 *
 * "Reducers" for entity operations like add and update.
 * Dragons!  No need to enter.
 *
 */ import { Observable } from 'rxjs' ; import { first } from 'rxjs/operators' ; import { CacheStore , cacheSnapShot , collectionSnapshot , EntityCache , EntityType } from './entity-cache' ; import { modelGuards } from './model-guards' ; param entity returns export function addEntity < T extends EntityType > ( entity , collectionName , cacheStore ) { const newEntity = addEntityGuard ( entity , collectionName , cacheStore ) ; cacheStore . pipe ( first ( ) ) . subscribe ( cache => { const coll = ( cache [ collectionName ] as any ) as T [ ] ; cache = { ... cache , [ collectionName ] : coll . concat ( newEntity as T ) } ; cacheStore . next ( cache ) ; } ) ; return entity ; } param entity returns export function updateEntity < T extends EntityType > ( entity , collectionName , cacheStore ) { const id = entity . id ; const update = updateEntityGuard ( entity , collectionName , cacheStore ) ; cacheStore . pipe ( first ( ) ) . subscribe ( cache => { const coll = ( cache [ collectionName ] as any ) as T [ ] ; cache = { ... cache , [ collectionName ] : coll . map ( e => ( e . id === id ? ( entity = { ... e , ... update } ) : e ) ) } ; cacheStore . next ( cache ) ; } ) ; return entity ; } /**
 * Ensure the entity you're about to add has an id, is not already in the collection,
 * has all and only the properties required, and its FKs (if any) are valid.
 */ function addEntityGuard < T extends { id : number ; } > ( entity , collectionName , cache$ ) { const id = entity . id ; if ( id == null ) { throw new Error ( `Cannot add a new entity to ${ collectionName } without an id.` ) ; } const bad = null != collectionSnapshot ( collectionName , cache$ ) . find ( ( e ) => e . id === id ) ; if ( bad ) { throw new Error ( `Cannot add entity with id:${ id } because it is already in the ${ collectionName } collection.` ) ; } const cache = cacheSnapShot ( cache$ ) ; return modelGuards [ collectionName ] ( entity , true , cache ) as T ; } /**
 * Ensure the entity you're about to update has an id, is already in the collection,
 * has all and only the properties required, and its FKs (if any) are valid.
 */ function updateEntityGuard < T extends { id : number ; } > ( entity , collectionName , cache$ ) { const id = entity . id ; if ( id == null ) { throw new Error ( `Cannot update an new entity to ${ collectionName } without an id.` ) ; } const bad = null == collectionSnapshot ( collectionName , cache$ ) . find ( ( e ) => e . id === id ) ; if ( bad ) { throw new Error ( `Cannot update and entity with id:${ id } because it cannot be found in the ${ collectionName } collection.` ) ; } const cache = cacheSnapShot ( cache$ ) ; return modelGuards [ collectionName ] ( entity , false , cache ) as T ; }