0.1.6 add isEmitter function

add makeObserver and have addObserver call it, allows making without storing to all combination
add save argument for subscribe which will save to list for easy subscribe.
master
David Kebler 2020-01-16 22:16:35 -08:00
parent 63566d624f
commit 2497321c66
3 changed files with 42 additions and 17 deletions

View File

@ -6,7 +6,7 @@ let emitter = new EventEmitter()
// let verbose = process.env.VERBOSE==='true'
let combo = false
let combo = true
// handler: (r)=> console.log('result:',r)
@ -74,11 +74,19 @@ if (combo) {
)
if (combo){
console.log('a combination of e and pr was made\n','combinations are not added to \'all\' list')
console.log('subscribing to sub combination e, pr')
example.subscribe('combo',val => console.log('combo e, pr is:',val))
}
}
let madeonly = example.makeObserver('madeonly')
console.log('observer \'madeonly\' was only made and was not added so not in list \n',madeonly)
console.log('list of observers made and added to the all combination\n',example.observerNames)
emitter.emit('ec',{ready:true})
emitter.emit('pe','yup')
emitter.emit('e')

View File

@ -1,6 +1,6 @@
{
"name": "@uci-utils/ready",
"version": "0.1.5",
"version": "0.1.6",
"description": "A Class to Observe the reduced to boolean combined state of a map of observables",
"main": "src/ready.js",
"scripts": {

View File

@ -10,7 +10,7 @@ import { createBoolean } from '@uci-utils/to-boolean'
class Ready extends Map {
constructor(opts) {
super(opts.observables)
this.emitter = typeof opts.emitter.on ==='function' ? opts.emitter : null
this.emitter = isEmitter(opts.emitter) ? opts.emitter : null
const toBool = createBoolean(opts.boolean) // e.g. {undefined:true}
this.condition = opts.condition || ( (ev) => toBool(ev) )
this.subscriptions = new Map()
@ -70,17 +70,17 @@ class Ready extends Map {
})
}
addObserver(name, obs, opts={} ) {
makeObserver(obs, opts={}) {
// validation and defaults, obs can be emitter, osbserver, or promise
if (!name || typeof(name)!=='string') return false // name required
if (isPlainObject(obs)) { opts = obs; obs=null }
if (!(obs || this.emitter)) return false // some observable requried
let { condition, event, details } = opts
let { condition, event, name} = opts
condition = condition || this.condition
if (typeof (obs ||{}).on ==='function') obs = fromEvent(obs, event || name) // it's an emitter
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 && !isObservable(obs) && typeof obs==='function' && arguments.length===2) condition = obs
if (!obs && this.emitter) obs = fromEvent(this.emitter,event || name)
if (!obs && this.emitter && (event || name)) obs = fromEvent(this.emitter,event || name)
if (!obs || !isObservable(obs)) return false
let xobs = obs.pipe(
tap(val => this.log(`${name} emitted/resolved the value =>${JSON.stringify(val)}`)),
@ -88,17 +88,27 @@ class Ready extends Map {
tap(val => this.log(`boolean: ${val}`)),
startWith(false),
shareReplay(1),
// multicast(new Subject())
)
let sub = xobs.subscribe()
this.set(name, {obs:xobs, sub:sub})
this.setObserverDetails(name,details)
this.combineObservers('__all__') // update total combo
if (this.subscriptions.has('__all__')) this.subscribe() // will resubscribe
xobs._readyType = true
return xobs
}
combineObservers(name,list) {
addObserver(name, obs, opts={} ) {
// validation and defaults, obs can be emitter, osbserver, or promise
if (!name || typeof(name)!=='string') return false // name required
opts.name = name
if (!(obs || {})._readyType) obs = this.makeObserver(obs, opts)
if (!isObservable(obs)) return false
let { details } = opts
let sub = obs.subscribe()
this.set(name, {obs:obs, sub:sub})
this.setObserverDetails(name,details)
this.combineObservers('__all__',opts) // update total combo
if (this.subscriptions.has('__all__')) this.subscribe() // will resubscribe
return obs
}
// TODO add option for whether changed is enabled (default) or not and store with combo for remake
combineObservers(name,list,opts={}) {
if (Array.isArray(name)) {list = name; name = null}
name = name || '__all__'
if (name==='__all__') list = Array.from(this.keys()) // get list of all observers
@ -136,7 +146,7 @@ class Ready extends Map {
this.subscribe() // resubscribe to changed combo
}
subscribe(name, handler) {
subscribe(name, handler, save) {
// only one subscription at a time per observer or combination from this method
if (typeof name ==='function') {
handler=name
@ -148,7 +158,7 @@ class Ready extends Map {
if (!obs) return false
if (this.subscriptions.has(name)) this.subscriptions.get(name).subs.unsubscribe()
let subs = obs.subscribe(handler)
this.subscriptions.set(name,{subs:subs,handler:handler})
if (save) this.subscriptions.set(name,{subs:subs,handler:handler})
return subs
}
@ -179,7 +189,14 @@ function map(fn) {
return isAsync(fn) ? switchMap.call(this,fn) : simpleMap.call(this,fn)
}
function isEmitter(emitter) {
if (!emitter) return false
let check = ['on','emit']
return check.reduce((acc,fn)=> acc && typeof emitter[fn] ==='function',true)
}
function isAsync(fn) {
if (typeof fn !== 'function') return false
return (isPromise(fn) || fn.constructor.name === 'AsyncFunction')
}