0.1.10 add makeCombination, fix bug in makeObserver, refactor failed, add sending boolean event as array where first element is ready value to check
parent
333d565894
commit
205f9a2ccd
|
@ -2,3 +2,4 @@ tests/
|
|||
test/
|
||||
*.test.js
|
||||
testing/
|
||||
examples/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@uci-utils/ready",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.10",
|
||||
"description": "A Class to Observe the reduced to boolean combined state of a map of observables",
|
||||
"main": "src/ready.js",
|
||||
"scripts": {
|
||||
|
@ -22,7 +22,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/uCOMmandIt/uci-utils#readme",
|
||||
"dependencies": {
|
||||
"@uci-utils/to-boolean": "^0.1.1",
|
||||
"@uci-utils/to-boolean": "^0.1.5",
|
||||
"is-observable": "^2.0.0",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"p-is-promise": "^3.0.0",
|
||||
|
@ -31,7 +31,7 @@
|
|||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"esm": "^3.2.25",
|
||||
"mocha": "^6.2.2",
|
||||
"nodemon": "^1.19.4"
|
||||
"mocha": "^7.0.1",
|
||||
"nodemon": "^2.0.2"
|
||||
}
|
||||
}
|
||||
|
|
57
src/ready.js
57
src/ready.js
|
@ -8,12 +8,14 @@ import isPlainObject from 'is-plain-object'
|
|||
import { createBoolean } from '@uci-utils/to-boolean'
|
||||
|
||||
class Ready extends Map {
|
||||
constructor(opts) {
|
||||
constructor(opts={}) {
|
||||
super(opts.observables)
|
||||
this.emitter = isEmitter(opts.emitter) ? opts.emitter : null
|
||||
const toBool = createBoolean(opts.boolean)
|
||||
this.toBoolean = (value) => {
|
||||
// can emit plain object with ready prop, or array with first value as ready value or just ready value
|
||||
if (isPlainObject(value)) value = (value.ready || value.online || value.active || false)
|
||||
if (Array.isArray(value)) value=value[0]
|
||||
return toBool(value)
|
||||
}
|
||||
this.condition = opts.condition || ( (ev) => this.toBoolean(ev) )
|
||||
|
@ -27,19 +29,26 @@ class Ready extends Map {
|
|||
if (opts.verbose||process.env.UCI_READY_VERBOSE==='true') this.logger.subscribe(console.log)
|
||||
this.handler = opts.handler || ((ready) => {console.log('default handler', ready)})
|
||||
this._first = true // tracks first emission
|
||||
console.log('@uci-utils/ready package tag 0.1.10')
|
||||
}
|
||||
|
||||
get observers(){return Array.from(this.keys())}
|
||||
get combinations(){return Array.from(this._combinations.keys())}
|
||||
get all() { return this._all}
|
||||
|
||||
get failure () {
|
||||
let ret = null
|
||||
let failed = this.state.some(obs=> {
|
||||
ret = obs[0]
|
||||
return obs[1]===false
|
||||
})
|
||||
return !failed ? '__none__' : ret
|
||||
get failed() {
|
||||
// console.log('making failures from',this.state)
|
||||
let failed = this.state
|
||||
.filter(([,ready]) => {
|
||||
// console.log('in filter', ready)
|
||||
// return !await this.getValue(name)
|
||||
// ret = obs[0]
|
||||
return !ready
|
||||
})
|
||||
.map(obs=> {return {name:obs[0], details: this.getObserverDetails(obs[0])} })
|
||||
// console.log('failed as filtered', failed)
|
||||
|
||||
return failed.length ? failed : '__none__'
|
||||
}
|
||||
|
||||
getObserverDetails(name) { return (this.get(name)||{}).details}
|
||||
|
@ -67,9 +76,10 @@ class Ready extends Map {
|
|||
getValue(name) { // NOT recommended. if there is any issue will return false
|
||||
let obs = this.getObserver(name)
|
||||
return new Promise(resolve => {
|
||||
setTimeout(()=>resolve(false),50)
|
||||
setTimeout(()=>resolve(false),100)
|
||||
if (isObservable(obs)){
|
||||
const sub = obs.subscribe(val => {
|
||||
console.log('in value subscriber', name,val)
|
||||
resolve(val)
|
||||
})
|
||||
sub.unsubscribe()
|
||||
|
@ -85,13 +95,18 @@ class Ready extends Map {
|
|||
condition = condition || this.condition
|
||||
if (isEmitter(obs) && (event || name)) obs = fromEvent(obs, event || name ) // it's an emitter
|
||||
if (isPromise(obs)) obs = from(obs) // it's a promise
|
||||
if (!obs && this.emitter && (event || name)) obs = fromEvent(this.emitter,(event || name))
|
||||
if ((!obs || typeof obs==='string') && this.emitter && (event || name || obs)) obs = fromEvent(this.emitter,(event || name || obs))
|
||||
if (!obs || !isObservable(obs)) return false
|
||||
let xobs = obs.pipe(
|
||||
tap(val => this.log(`${name} emitted/resolved the value =>${JSON.stringify(val)}`)),
|
||||
// tap(val => console.log(`${name} emitted/resolved the value =>${JSON.stringify(val)}`)),
|
||||
// TODO retain plain object if it has a ready property
|
||||
map(condition),
|
||||
// tap(val => console.log(`boolean: ${val}`)),
|
||||
tap(val => this.log(`boolean: ${val}`)),
|
||||
map(val => {
|
||||
// if (opts.reverse) console.log('reversing', val, opts.reverse ? !val : val)
|
||||
return opts.reverse ? !val : val}),
|
||||
startWith(false),
|
||||
// shareReplay({refCount:true, bufferSize:1}),
|
||||
shareReplay(1),
|
||||
|
@ -131,6 +146,19 @@ class Ready extends Map {
|
|||
// TODO update affected combinations
|
||||
}
|
||||
|
||||
// TODO have combineObservers call this
|
||||
makeCombination(observers,list){
|
||||
observers = observers.filter(obs=>obs._readyType)
|
||||
if (!observers.length) return false
|
||||
let combination = combineLatest(observers).pipe(
|
||||
tap(states => { if (list) this.log(list.map((name,index) => [name,states[index]]))}),
|
||||
map(states => states.reduce((res,state) => {return res && state},true)),
|
||||
changed(), //filters out emission if it is unchanged from last TODO replace with distinctUntilChanged
|
||||
shareReplay(1)
|
||||
)
|
||||
return combination
|
||||
}
|
||||
|
||||
// TODO add option for whether changed is enabled (default) or not and store with combo for remake
|
||||
combineObservers(name,list,opts={}) {
|
||||
if (!name || typeof(name)!=='string') return false // name required
|
||||
|
@ -141,14 +169,7 @@ class Ready extends Map {
|
|||
else return false
|
||||
}
|
||||
let observers = list.map(name=>{return name._readyType ? name : this.getObserver(name)})
|
||||
observers = observers.filter(obs=>obs._readyType)
|
||||
if (!observers.length) return false
|
||||
let combination = combineLatest(observers).pipe(
|
||||
tap(states => { this.log(list.map((name,index) => [name,states[index]]))}),
|
||||
map(states => states.reduce((res,state) => {return res && state},true)),
|
||||
changed(), //filters out emission if it is unchanged from last
|
||||
shareReplay(1)
|
||||
)
|
||||
const combination = this.makeCombination(observers,list)
|
||||
this._combinations.set(name, combination) // if name passed then save combo in Map
|
||||
return combination
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue