import { Injectable , OnDestroy } from '@angular/core' ; import { Subject } from 'rxjs' ; import { ConduitSubject } from './conduit-subject' ; import { ConduitEvent } from './interfaces/conduit-event' ; import { ConduitMetadata } from './interfaces/conduit-metadata' ; import { ConduitProperties } from './interfaces/conduit-properties' ; @ Injectable ( ) export class ConduitZone implements OnDestroy { /** Create a global subject store */ static subjects : ConduitSubject [ ] = [ ] ; /** Expose an event stream of new values */ static events = new Subject < ConduitEvent > ( ) ; /** Store the zone name */ private _zoneId : string ; ngOnDestroy ( ) { ConduitZone . subjects . filter ( _subject => _subject . zoneId === this . _zoneId ) . forEach ( _subject => this . unregisterConduit ( _subject . conduit ) ) ; } /** Store reference to the repository and begin watching for and emitting changes */ registerConduit ( conduit ) { ConduitZone . subjects . push ( new ConduitSubject ( conduit , this , this . _zoneId ) ) ; } /** Destroy a conduit */ unregisterConduit ( conduit ) { const subject = this . getConduitSubject ( conduit . subject ) ; if ( subject ) { ConduitZone . subjects = ConduitZone . subjects . filter ( _subject => _subject !== subject ) ; subject . destroy ( ) ; } } /** Provide the zone with an ID */ setZoneId ( zoneId ) { this . _zoneId = zoneId ; } /** Emit a value to all zones for checking */ emit ( event ) { ConduitZone . events . next ( event ) ; } /** Retrieve a conduit subsject object from the rxjs subject */ getConduitSubject ( subject ) { return ConduitZone . subjects . find ( _subject => _subject . conduit . subject === subject ) ; } /** Get all subjects from all zones */ getSubjects ( ) { return ConduitZone . subjects ; } /** Alter the properties of a conduit dynamically */ setConduitProperties ( subject , properties ) { const conduitSubject = this . getSubjects ( ) . find ( _conduit => _conduit . conduit . subject === subject ) ; if ( conduitSubject ) { for ( const prop in properties ) { conduitSubject . conduit [ prop ] = properties [ prop ] ; } } } /** Programmatically create a conduit at runtime */ createConduit ( subject , properties ) { this . registerConduit ( { ... properties , subject } ) ; } /** Register all conduits in a component */ registerConduits ( component ) { if ( Array . isArray ( component . _conduits ) ) { component . _conduits . forEach ( ( conduit ) => this . registerConduit ( { ... conduit , subject : component [ conduit . propertyKey ] } ) ) ; } } /** Register all conduits in a component */ unregisterConduits ( component ) { if ( Array . isArray ( component . _conduits ) ) { component . _conduits . forEach ( ( conduit ) => this . unregisterConduit ( conduit ) ) ; } } /** Return the global event stream */ getEvents ( ) { return ConduitZone . events ; } }