import EventEmitter from './EventEmitter' ; import { IAgent , MoleculeOptions } from './defs' ; import Agent from './Agent' ; import MainRegistry , { createRegistry , ComponentRegistry , } from './ComponentRegistry' ; export default class Molecule { name : string = 'anonymous' ; config : any = { } ; debug : boolean = false ; agents : { [ key ] : any ; } = { } ; emitter : EventEmitter ; store : any = { } ; registry : ComponentRegistry ; parent ? : Molecule ; children : Molecule [ ] = [ ] ; constructor ( value , parent ? ) { const { config , agents , store , registry , name , debug } = value ; this . debug = ! ! debug ; if ( parent ) { this . parent = parent ; parent . children . push ( this ) ; } this . emitter = new EventEmitter ( { context : name , debug , parent : parent ? parent . emitter : null , } ) ; this . registry = createRegistry ( { } , MainRegistry ) ; if ( value . registry ) { this . registry . blend ( value . registry , { } ) ; } if ( value . agents ) { this . storeAgents ( value . agents ) ; } if ( value . name ) { this . name = value . name ; } if ( value . store ) { this . store = value . store ; } if ( config ) { this . config = config ; } } get root ( ) { if ( ! this . parent ) { return this ; } return this . parent . root ; } init ( ) { for ( let agentName in this . agents ) { const agent = this . agents [ agentName ] ; agent . prepare ( ) ; } for ( let agentName in this . agents ) { const agent = this . agents [ agentName ] ; if ( ! agent . preventInit ) { agent . init ( ) ; } } } clean ( ) { if ( this . parent ) { this . parent . children = this . parent . children . filter ( molecule => molecule !== this ) ; } this . emitter . removeAllListeners ( ) ; for ( let agentName in this . agents ) { const agent = this . agents [ agentName ] ; agent . emitter . removeAllListeners ( ) ; agent . clean ( ) ; } } public on ( event , handler ) { this . emitter . on ( event , handler ) ; } public once ( event , handler ) { this . emitter . once ( event , handler ) ; } public off ( event , handler ) { this . emitter . off ( event , handler ) ; } public emit ( event , ... args ) { this . emitter . emit ( event , ... args ) ; } public deepmit ( event , ... args ) { this . emit ( event , ... args ) ; this . children . forEach ( child => { child . deepmit ( event , ... args ) ; } ) ; } param name closest ( name ) { if ( this . name === name ) { return this ; } if ( this . parent ) { return this . parent . closest ( name ) ; } return null ; } getAgent ( name ) { const agent = this . agents [ name ] ; if ( ! agent ) { throw new Error ( `We could not find the agent with name: "${ name }" inside this molecule.` ) ; } return agent ; } param _agents private storeAgents ( _agents ) { let agents = { } ; for ( let agentName in _agents ) { agents [ agentName ] = _agents [ agentName ] ( this ) ; } this . agents = agents ; } }