0.1.2 Only emits on change of state

Added logging
uses external to boolean package
master
David Kebler 2020-01-02 14:56:03 -08:00
parent 3eef450669
commit be1cf69996
3 changed files with 27 additions and 43 deletions

View File

@ -4,7 +4,9 @@ import { EventEmitter } from 'events'
let emitter = new EventEmitter() let emitter = new EventEmitter()
let process = new Ready({emitter: emitter}) // handler: (r)=> console.log('result:',r)
let process = new Ready({emitter: emitter, verbose:true})
const tObs = new Observable(subscriber => { const tObs = new Observable(subscriber => {
subscriber.next('on') subscriber.next('on')
@ -17,7 +19,7 @@ const tObs = new Observable(subscriber => {
}) })
const tPromise = new Promise(function(resolve) { const tPromise = new Promise(function(resolve) {
setTimeout(()=>resolve('yes'),3000) setTimeout(()=>resolve('yes'),1500)
}) })
process.addObserver('e') process.addObserver('e')
@ -26,8 +28,9 @@ process.addObserver('pe',emitter)
process.addObserver('obs',tObs) process.addObserver('obs',tObs)
process.addObserver('pr',tPromise) process.addObserver('pr',tPromise)
console.log(process.size) process.subscribe(val => console.log('---------------Ready Changed to :',val))
process.subscribe() // process.subscribe('obs',val => console.log('obs',val))
emitter.emit('ec',{test:true}) emitter.emit('ec',{test:true})
emitter.emit('e','sure') emitter.emit('e','sure')

View File

@ -1,6 +1,6 @@
{ {
"name": "@uci-utils/ready", "name": "@uci-utils/ready",
"version": "0.1.1", "version": "0.1.2",
"description": "A Class to Observe the reduced to boolean combined state of a map of observables", "description": "A Class to Observe the reduced to boolean combined state of a map of observables",
"main": "src/ready.js", "main": "src/ready.js",
"scripts": { "scripts": {
@ -26,6 +26,7 @@
}, },
"homepage": "https://github.com/uCOMmandIt/uci-utils#readme", "homepage": "https://github.com/uCOMmandIt/uci-utils#readme",
"dependencies": { "dependencies": {
"@uci-utils/to-boolean": "^0.1.1",
"is-observable": "^2.0.0", "is-observable": "^2.0.0",
"p-is-promise": "^3.0.0", "p-is-promise": "^3.0.0",
"rxjs": "^6.5.4" "rxjs": "^6.5.4"

View File

@ -1,11 +1,10 @@
import { from, fromEvent, combineLatest } from 'rxjs' import { from, fromEvent, combineLatest, Subject } from 'rxjs'
import { map, startWith, tap } from 'rxjs/operators' import { map, startWith, tap, pairwise, filter } from 'rxjs/operators'
import isObservable from 'is-observable' import isObservable from 'is-observable'
import isPromise from 'p-is-promise' import isPromise from 'p-is-promise'
// UCI dependencies
import { createBoolean } from '../../to-boolean' import { createBoolean } from '@uci-utils/to-boolean'
const toBool = createBoolean({undefined:true}) // make default make null event emission cast to TRUE
const toBool = createBoolean({undefined:true})
class Ready extends Map { class Ready extends Map {
constructor(opts) { constructor(opts) {
@ -15,8 +14,11 @@ class Ready extends Map {
this.condition = opts.condition || ( (ev) => toBool(ev) ) this.condition = opts.condition || ( (ev) => toBool(ev) )
this.subscriptions = new Map() this.subscriptions = new Map()
this._state = {} this._state = {}
this._updateObserversList() this.logger = new Subject()
this.handler = opts.handler || ( ([r,s]) => {console.log('ready:',r,'states:',s,'\n---------------------------')}) this.log = this.logger.next.bind(this.logger)
if (opts.verbose) this.logger.subscribe(console.log)
this._updateObserversList() // initialize
this.handler = opts.handler || console.log
} }
get state() {return this._state} get state() {return this._state}
@ -34,9 +36,9 @@ class Ready extends Map {
if (!obs || !isObservable(obs)) return false if (!obs || !isObservable(obs)) return false
this.set(name, obs this.set(name, obs
.pipe( .pipe(
tap((ev) => console.log(name,'emitted/resolved=>',ev)), tap(val => this.logger.next(`${name} emitted/resolved the value =>${JSON.stringify(val)}`)),
map(condition||this.condition), map(condition||this.condition),
tap((b) => console.log('boolean:',b)), tap(val => this.log(`boolean: ${val}`)),
startWith(false), startWith(false),
) )
) )
@ -69,37 +71,15 @@ class Ready extends Map {
_updateObserversList() { _updateObserversList() {
this._state = combineLatest(Array.from(this.values())).pipe( this._state = combineLatest(Array.from(this.values())).pipe(
// tap((states)=>console.log('states',states)), tap(states => this.log( Array.from(this.keys()).map((name,index) => [name,states[index]]))),
map(states=> { map( states => states.reduce((res,state) => {return res && state},true)),
return [states.reduce((res,state) => {return res && state},true), Array.from(this.keys()).map((name,index) => [name,states[index]])] pairwise(),
}) filter( ([p,c]) => (p ^ c)), // only emit on change
map( r => r[1] ) //remove previous
) )
} }
}
// const toBoolean = (cond) => } // end class
// pipe(
// map(cond),
// startWith(false),
// )
const rTrue=['t','true','y','yes','on','positive','up','enabled','affirmative','yea']
const rFalse=['f','false','n','no','off','negative','down','disabled','nope']
function castBoolean (opts={}) {
return (value => {
if (value===undefined) return opts.undefined
if (value===null) return opts.null
if (!isNaN(Number(value))) return Number(value) <1 ? false :true
if (typeof value==='string') {
value = value.trim()
value = value.toLowerCase()
if ((opts.rTrue || rTrue).includes(value)) return true
if ((opts.rFalse || rFalse).includes(value)) return false
}
return !!value
})
}
export default Ready export default Ready
export { Ready } export { Ready }