/** * @classdesc The main Snaptobus class * @author Nike * @version 1.0 */ class Snaptobus{ constructor(config){ this.config = this.observeObject(config, this.configChange.bind(this)) } observeObject(obj, onChange) { const wrap = (value) => (value && typeof value === 'object') ? this.observeObject(value, onChange) : value const handler = { set: (target, prop, value) => { const oldValue = target[prop] target[prop] = wrap(value) onChange(prop, value, oldValue, target) return true }, deleteProperty: (target, prop) => { const oldValue = target[prop] delete target[prop] onChange(prop, undefined, oldValue, target) return true } } // Walk initial keys/elements (construction time) for (const key of Object.keys(obj)) { obj[key] = wrap(obj[key]) } return new Proxy(obj, handler) } configChange(prop, newval, oldval){ //TODO subscribe new chans //TODO unsubscribe removed chans //TODO update event filters // console.log(prop, oldval, newval) } getValueByPath(obj, path) { return(path.split('.').reduce((acc, key) => acc?.[key], obj)) } assignFromConfig(chan, event) { const result = {} for (const [key, rule] of Object.entries(this.config.assign)) { if (typeof rule === 'string') { // plain path result[key] = this.getValueByPath(event, rule) } else if((typeof(rule) == 'object') && (typeof(rule.transformer) == 'function')) { // transformer const fnargs = (rule.arguments || []).map(arg => this.getValueByPath(event,arg)) result[key] = rule.transformer(...fnargs) } } return result } } /* const s2bConfig = [ { chan: 'gps:agents', // What to subscribe to events: [ // What to select on this chan { eventName: 'moving', snaps: [ { // selector will be used as css selector for a snap element / group, // with LAST MINUTE template resolving of event properties (with eventual dots) selector: '#${aid}', assign: { x: 'coords.x', // type string: event property, eventual dots to go down object y: 'coords.y', }, animate: true } ] }, ] }, { chan: 'agent:*', // wildcards allowed events: [ { eventName: 'aging', snaps: [ { selector: '#{aid}', assign: { fill: { // transformer function arguments: [ 'age' ], // What to give from the event as function's params transformer: i => `rgb(${Math.round(255 * i / 10)},0,${Math.round(255 * (1 - i / 10))})` }, }, } ] }, ] }, ] */