PHP Classes

File: src/js/PublishSubscribe.js

Recommend this page to a friend!
  Classes of Nikos M.  >  PHP Publish Subscribe  >  src/js/PublishSubscribe.js  >  Download  
File: src/js/PublishSubscribe.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: PHP Publish Subscribe
Register and call handlers of events by name
Author: By
Last change:
Date: 2 years ago
Size: 33,946 bytes
 

Contents

Class file image Download
/** * PublishSubscribe * A simple publish-subscribe implementation for PHP, Python, Node/XPCOM/JS * * @version: 1.1.0 * https://github.com/foo123/PublishSubscribe * **/ !function( root, name, factory ){ "use strict"; if ( ('undefined'!==typeof Components)&&('object'===typeof Components.classes)&&('object'===typeof Components.classesByID)&&Components.utils&&('function'===typeof Components.utils['import']) ) /* XPCOM */ (root.$deps = root.$deps||{}) && (root.EXPORTED_SYMBOLS = [name]) && (root[name] = root.$deps[name] = factory.call(root)); else if ( ('object'===typeof module)&&module.exports ) /* CommonJS */ (module.$deps = module.$deps||{}) && (module.exports = module.$deps[name] = factory.call(root)); else if ( ('undefined'!==typeof System)&&('function'===typeof System.register)&&('function'===typeof System['import']) ) /* ES6 module */ System.register(name,[],function($__export){$__export(name, factory.call(root));}); else if ( ('function'===typeof define)&&define.amd&&('function'===typeof require)&&('function'===typeof require.specified)&&require.specified(name) /*&& !require.defined(name)*/ ) /* AMD */ define(name,['module'],function(module){factory.moduleUri = module.uri; return factory.call(root);}); else if ( !(name in root) ) /* Browser/WebWorker/.. */ (root[name] = factory.call(root)||1)&&('function'===typeof(define))&&define.amd&&define(function(){return root[name];} ); }( /* current root */ 'undefined' !== typeof self ? self : this, /* module name */ "PublishSubscribe", /* module factory */ function ModuleFactory__PublishSubscribe( undef ){ "use strict"; var __version__ = "1.1.0", PROTO = 'prototype', HAS = Object[PROTO].hasOwnProperty, TOPIC_SEP = '/', TAG_SEP = '#', NS_SEP = '@', OTOPIC_SEP = '/', OTAG_SEP = '#', ONS_SEP = '@', KEYS = Object.keys, NOW = Date.now ? Date.now : function( ){ return new Date().getTime(); } ; function PublishSubscribeData( props ) { if ( props ) { for (var k in props) { if ( HAS.call(props,k) ) this[ k ] = props[ k ]; } } } PublishSubscribeData[PROTO] = { constructor: PublishSubscribeData, dispose: function( props ) { if ( props ) { for (var k=0; k<props.length; k++) { this[ props[ k ] ] = null; } } return this; } }; function PublishSubscribeEvent(target, topic, original, tags, namespaces) { var self = this; self.target = target; if ( topic ) self.topic = [].concat( topic ); else self.topic = [ ]; if ( original ) self.originalTopic = [].concat( original ); if ( tags ) self.tags = [].concat( tags ); else self.tags = [ ]; if ( namespaces ) self.namespaces = [].concat( namespaces ); else self.namespaces = [ ]; self.data = null;//new PublishSubscribeData(); self.timestamp = NOW( ); self._propagates = true; self._stopped = false; self._aborted = false; } PublishSubscribeEvent[PROTO] = { constructor: PublishSubscribeEvent, target: null, topic: null, originalTopic: null, tags: null, namespaces: null, data: null, timestamp: 0, is_pipelined: false, _next: null, _propagates: true, _stopped: false, _aborted: false, dispose: function( ) { var self = this; self.target = null; self.topic = null; self.originalTopic = null; self.tags = null; self.namespaces = null; if (self.data instanceof PublishSubscribeData) self.data.dispose(); self.data = null; self.timestamp = null; self.is_pipelined = false; self._propagates = true; self._stopped = true; self._aborted = false; self._next = null; return self; }, next: function( ) { if ('function' === typeof this._next) this._next(this); return this; }, pipeline: function( next ) { if ( !arguments.length ) next = null; if ('function' === typeof next) { this._next = next; this.is_pipelined = true; } else { this._next = null; this.is_pipelined = false; } return this; }, propagate: function( enable ) { if ( !arguments.length ) enable = true; this._propagates = !!enable; return this; }, stop: function( enable ) { if ( !arguments.length ) enable = true; this._stopped = !!enable; return this; }, abort: function( enable ) { if ( !arguments.length ) enable = true; this._aborted = !!enable; return this; }, aborted: function( ) { return this._aborted; }, propagates: function( ) { return this._propagates; }, stopped: function( ) { return this._stopped; } }; function get_pubsub( ) { return { notopics: { notags: {namespaces: {}, list: [], oneOffs: 0}, tags: {} }, topics: {} }; } function not_empty( s ) { return s.length > 0; } function parse_topic( seps, topic ) { var nspos, tagspos, tags, namespaces; topic = String( topic ); nspos = topic.indexOf( seps[2] ); tagspos = topic.indexOf( seps[1] ); if ( -1 < nspos ) { namespaces = topic .slice( nspos ) .split( seps[2] ) .filter( not_empty ) .sort( ) ; topic = topic.slice( 0, nspos ); } else { namespaces = [ ]; } if ( -1 < tagspos ) { tags = topic .slice( tagspos ) .split( seps[1] ) .filter( not_empty ) .sort( ) ; topic = topic.slice( 0, tagspos ); } else { tags = [ ]; } topic = topic.split( seps[0] ).filter( not_empty ); return [topic, tags, namespaces]; } function get_all_topics( seps, topic ) { var topics = [ ], tags = [ ], namespaces/* = [ ]*/, ttags, tns, l, i, j, jj, tmp, combinations; topic = parse_topic( seps, topic ); //tns = topic[2]; namespaces = topic[2]; ttags = topic[1]; topic = topic[0]; l = topic.length; while ( l ) { topics.push( topic.join( OTOPIC_SEP ) ); topic.pop( ); l--; } l = ttags.length; if ( l > 1 ) { combinations = (1 << l); for (i=combinations-1; i>=1; i--) { tmp = [ ]; for (j=0,jj=1; j<l; j++,jj=(1 << j)) { if ( (i !== jj) && (i & jj) ) tmp.push( ttags[ j ] ); } if ( tmp.length ) tags.push( tmp.join( OTAG_SEP ) ); } tags = tags.concat( ttags ); } else if ( l ) tags.push( ttags[ 0 ] ); /*l = tns.length; if ( l > 1 ) { combinations = (1 << l); for (i=combinations-1; i>=1; i--) { tmp = [ ]; for (j=0,jj=1; j<l; j++,jj=(1 << j)) { if ( (i !== jj) && (i & jj) ) tmp.push( tns[ j ] ); } if ( tmp.length ) namespaces.push( tmp.join( OMS_SEP ) ); } namespaces = namespaces.concat( tns ); } else if ( l && tns[0].length ) namespaces.push( tns[ 0 ] );*/ return [topics.length ? topics[0] : '', topics, tags, namespaces]; } function update_namespaces( pbns, namespaces, nl ) { var n, ns; for (n=0; n<nl; n++) { ns = 'ns_' + namespaces[n]; if ( !HAS.call(pbns,ns) ) { pbns[ ns ] = 1; } else { pbns[ ns ]++; } } } function remove_namespaces( pbns, namespaces, nl ) { var n, ns; for (n=0; n<nl; n++) { ns = 'ns_' + namespaces[n]; if ( HAS.call(pbns,ns) ) { pbns[ ns ]--; if ( pbns[ ns ] <=0 ) delete pbns[ ns ]; } } } function match_namespace( pbns, namespaces, nl ) { var n, ns; for (n=0; n<nl; n++) { ns = 'ns_' + namespaces[n]; if ( !HAS.call(pbns,ns) || (0 >= pbns[ ns ]) ) return false; } return true; } function check_is_subscribed( pubsub, subscribedTopics, topic, tag, namespaces, nl ) { var _topic = !!topic ? 'tp_' + topic : false, _tag = !!tag ? 'tg_' + tag : false; if ( _topic && HAS.call(pubsub.topics,_topic) ) { if ( _tag && HAS.call(pubsub.topics[ _topic ].tags,_tag) ) { if ( pubsub.topics[ _topic ].tags[ _tag ].list.length && (nl <= 0 || match_namespace( pubsub.topics[ _topic ].tags[ _tag ].namespaces, namespaces, nl )) ) { subscribedTopics.push( [topic, tag, nl > 0, pubsub.topics[ _topic ].tags[ _tag ]] ); return true; } } else { if ( pubsub.topics[ _topic ].notags.list.length && (nl <= 0 || match_namespace( pubsub.topics[ _topic ].notags.namespaces, namespaces, nl )) ) { subscribedTopics.push( [topic, null, nl > 0, pubsub.topics[ _topic ].notags] ); return true; } } } else { if ( _tag && HAS.call(pubsub.notopics.tags,_tag) ) { if ( pubsub.notopics.tags[ _tag ].list.length && (nl <= 0 || match_namespace( pubsub.notopics.tags[ _tag ].namespaces, namespaces, nl )) ) { subscribedTopics.push( [null, tag, nl > 0, pubsub.notopics.tags[ _tag ]] ); return true; } } else { if ( pubsub.notopics.notags.list.length && (nl <= 0 || match_namespace( pubsub.notopics.notags.namespaces, namespaces, nl )) ) { subscribedTopics.push( [null, null, true, pubsub.notopics.notags] ); return true; } /* else no topics no tags no namespaces, do nothing */ } } return false; } function get_subscribed_topics( seps, pubsub, atopic ) { var all = get_all_topics( seps, atopic ), l, topic, tag, ns, //_topic, _tag, t, n, tl, nl, topics = all[ 1 ], tags = all[ 2 ], namespaces = all[ 3 ], topTopic = all[ 0 ], subscribedTopics = [ ] ; tl = tags.length; nl = namespaces.length; l = topics.length; if ( l ) { while ( l ) { topic = topics[ 0 ]; //_topic = 'tp_' + topic; if ( HAS.call(pubsub.topics, 'tp_' + topic) ) { if ( tl > 0 ) { for (t=0; t<tl; t++) { tag = tags[ t ]; //_tag = 'tg_' + tag; check_is_subscribed( pubsub, subscribedTopics, topic, tag, namespaces, nl ); } } else { check_is_subscribed( pubsub, subscribedTopics, topic, null, namespaces, nl ); } } topics.shift( ); l--; } } if ( tl > 0 ) { for (t=0; t<tl; t++) { tag = tags[ t ]; check_is_subscribed( pubsub, subscribedTopics, null, tag, namespaces, nl ); } } check_is_subscribed( pubsub, subscribedTopics, null, null, namespaces, nl ); /*nss = { }; if ( nl > 0 ) { for (n=0; n<nl; n++) { nss[ namespaces[ n ] ] = 1; } }*/ return [topTopic, subscribedTopics, namespaces]; } function unsubscribe_oneoffs( subscribers ) { if ( subscribers && HAS.call(subscribers,"list") ) { // unsubscribeOneOffs var s, sl, subs, subscriber; if ( (subs=subscribers.list) && (sl=subs.length) ) { if ( subscribers.oneOffs > 0 ) { for (s=sl-1; s>=0; s--) { subscriber = subs[ s ]; if ( subscriber[1] && subscriber[4] > 0 ) { subs.splice( s, 1 ); subscribers.oneOffs = subscribers.oneOffs > 0 ? (subscribers.oneOffs-1) : 0; } } } else { subscribers.oneOffs = 0; } } } return subscribers; } function publish( target, seps, pubsub, topic, data ) { if ( pubsub ) { var topics = get_subscribed_topics( seps, pubsub, topic ), t, s, tl, sl, subs, subscribers, subscriber, topTopic, subTopic, tags, namespaces, hasNamespace, nl, evt, res = false, pos, nskeys ; topTopic = topics[ 0 ]; namespaces = topics[ 2 ]; nl = namespaces.length; topics = topics[ 1 ]; tl = topics.length; evt = null; if ( tl > 0 ) { evt = new PublishSubscribeEvent( target ); evt.data = data; evt.originalTopic = topTopic ? topTopic.split( OTOPIC_SEP ) : [ ]; } for (t=0; t<tl; t++) { subTopic = topics[ t ][ 0 ]; tags = topics[ t ][ 1 ]; evt.topic = subTopic ? subTopic.split( OTOPIC_SEP ) : [ ]; evt.tags = tags ? tags.split( OTAG_SEP ) : [ ]; hasNamespace = topics[ t ][ 2 ]; subscribers = topics[ t ][ 3 ]; // create a copy avoid mutation of pubsub during notifications subs = [ ]; sl = subscribers.list.length; for (s=0; s<sl; s++) { subscriber = subscribers.list[ s ]; if ( (!subscriber[ 1 ] || !subscriber[ 4 ]) && (!hasNamespace || (subscriber[ 2 ] && match_namespace(subscriber[ 2 ], namespaces, nl))) ) { subs.push( subscriber ); } } sl = subs.length; for (s=0; s<sl; s++) { subscriber = subs[ s ]; //if ( subscriber[ 1 ] && subscriber[ 4 ] > 0 ) continue; // oneoff subscriber already called if ( hasNamespace ) evt.namespaces = subscriber[ 3 ].slice( 0 ); else evt.namespaces = [ ]; subscriber[ 4 ] = 1; // subscriber called res = subscriber[ 0 ]( evt ); // stop event propagation if ( (false === res) || evt.stopped() || evt.aborted() ) break; } // unsubscribeOneOffs unsubscribe_oneoffs( subscribers ); // stop event bubble propagation if ( evt.aborted() || !evt.propagates() ) break; } if ( evt ) { evt.dispose( ); evt = null; } } } function create_pipeline_loop( evt, topics, abort, finish ) { var topTopic = topics[ 0 ], namespaces = topics[ 2 ], topics = topics[ 1 ]; evt.non_local = new PublishSubscribeData({ 't': 0, 's': 0, 'start_topic': true, 'subscribers': null, 'topics': topics, 'namespaces': namespaces, 'hasNamespace': false, 'abort': abort, 'finish': finish }); evt.originalTopic = topTopic ? topTopic.split( OTOPIC_SEP ) : [ ]; var pipeline_loop = function pipeline_loop( evt ) { if ( !evt.non_local ) return; var res, non_local = evt.non_local, subTopic, tags, subscriber, done, abort, finish; if (non_local.t < non_local.topics.length) { if (non_local.start_topic) { // unsubscribeOneOffs unsubscribe_oneoffs( non_local.subscribers ); // stop event propagation if ( evt.aborted() || !evt.propagates() ) { if ( evt.aborted() && 'function' === typeof non_local.abort ) { abort = non_local.abort; non_local.abort = null; abort( evt ); if ( 'function' === typeof non_local.finish ) { finish = non_local.finish; non_local.finish = null; finish( evt ); } } return false; } subTopic = non_local.topics[ non_local.t ][ 0 ]; tags = non_local.topics[ non_local.t ][ 1 ]; evt.topic = subTopic ? subTopic.split( OTOPIC_SEP ) : [ ]; evt.tags = tags ? tags.split( OTAG_SEP ) : [ ]; non_local.hasNamespace = non_local.topics[ non_local.t ][ 2 ]; non_local.subscribers = non_local.topics[ non_local.t ][ 3 ]; non_local.s = 0; non_local.start_topic = false; } //if (non_local.subscribers) non_local.sl = non_local.subscribers.list.length; if (non_local.s < non_local.subscribers.list.length) { // stop event propagation if ( evt.aborted() || evt.stopped() ) { // unsubscribeOneOffs unsubscribe_oneoffs( non_local.subscribers ); if ( evt.aborted() && 'function' === typeof non_local.abort ) { abort = non_local.abort; non_local.abort = null; abort( evt ); if ( 'function' === typeof non_local.finish ) { finish = non_local.finish; non_local.finish = null; finish( evt ); } } return false; } done = false; while ( non_local.s < non_local.subscribers.list.length && !done ) { subscriber = non_local.subscribers.list[ non_local.s ]; if ( (!subscriber[ 1 ] || !subscriber[ 4 ]) && (!non_local.hasNamespace || (subscriber[ 2 ] && match_namespace(subscriber[ 2 ], non_local.namespaces, non_local.namespaces.length))) ) { done = true; } non_local.s += 1; } if (non_local.s >= non_local.subscribers.list.length) { non_local.t += 1; non_local.start_topic = true; } if ( done ) { if ( non_local.hasNamespace ) evt.namespaces = subscriber[ 3 ].slice( 0 ); else evt.namespaces = [ ]; subscriber[ 4 ] = 1; // subscriber called res = subscriber[ 0 ]( evt ); } } else { non_local.t += 1; non_local.start_topic = true; } } if ( !evt.non_local ) return; if (non_local.t >= non_local.topics.length) { // unsubscribeOneOffs unsubscribe_oneoffs( non_local.subscribers ); if ( 'function' === typeof non_local.finish ) { finish = non_local.finish; non_local.finish = null; finish( evt ); } if ( evt ) { evt.non_local.dispose([ 't', 's', 'start_topic', 'subscribers', 'topics', 'namespaces', 'hasNamespace', 'abort', 'finish' ]); evt.non_local = null; evt.dispose(); evt = null; } } }; return pipeline_loop; } function pipeline( target, seps, pubsub, topic, data, abort, finish ) { if ( pubsub ) { var topics = get_subscribed_topics( seps, pubsub, topic ), evt = null, pipeline_loop; if ( topics[ 1 ].length > 0 ) { evt = new PublishSubscribeEvent( target ); evt.data = data; evt.pipeline( pipeline_loop = create_pipeline_loop( evt, topics, abort, finish ) ); pipeline_loop( evt ); } } } function subscribe( seps, pubsub, topic, subscriber, oneOff, on1 ) { if ( pubsub && "function" === typeof(subscriber) ) { topic = parse_topic( seps, topic ); var tags = topic[1].join( OTAG_SEP ), tagslen = tags.length, entry, queue, _topic, _tag, namespaces = topic[2], nshash, namespaces_ref, n, nslen = namespaces.length; topic = topic[0].join( OTOPIC_SEP ); oneOff = (true === oneOff); on1 = (true === on1); nshash = { }; if ( nslen ) { for (n=0; n<nslen; n++) { nshash['ns_'+namespaces[n]] = 1; } } namespaces_ref = namespaces.slice( 0 ); queue = null; if ( topic.length ) { _topic = 'tp_' + topic; if ( !HAS.call(pubsub.topics,_topic) ) pubsub.topics[ _topic ] = { notags: {namespaces: {}, list: [], oneOffs: 0}, tags: {} }; if ( tagslen ) { _tag = 'tg_' + tags; if ( !HAS.call(pubsub.topics[ _topic ].tags,_tag) ) pubsub.topics[ _topic ].tags[ _tag ] = {namespaces: {}, list: [], oneOffs: 0}; queue = pubsub.topics[ _topic ].tags[ _tag ]; } else { queue = pubsub.topics[ _topic ].notags; } } else { if ( tagslen ) { _tag = 'tg_' + tags; if ( !HAS.call(pubsub.notopics.tags,_tag) ) pubsub.notopics.tags[ _tag ] = {namespaces: {}, list: [], oneOffs: 0}; queue = pubsub.notopics.tags[ _tag ]; } else if ( nslen ) { queue = pubsub.notopics.notags; } } if ( null !== queue ) { entry = nslen ? [subscriber, oneOff, nshash, namespaces_ref, 0] : [subscriber, oneOff, false, [], 0] ; if ( on1 ) queue.list.unshift( entry ); else queue.list.push( entry ); if ( oneOff ) queue.oneOffs++; if ( nslen ) update_namespaces( queue.namespaces, namespaces, nslen ); } } } function remove_subscriber( pb, hasSubscriber, subscriber, namespaces, nslen ) { var pos = pb.list.length, nskeys; if ( hasSubscriber ) { if ( (null != subscriber) && (pos > 0) ) { while ( --pos >= 0 ) { if ( subscriber === pb.list[pos][0] ) { if ( nslen && pb.list[pos][2] && match_namespace( pb.list[pos][2], namespaces, nslen ) ) { nskeys = KEYS(pb.list[pos][2]); remove_namespaces( pb.namespaces, nskeys, nskeys.length ); if ( pb.list[pos][1] ) pb.oneOffs = pb.oneOffs > 0 ? (pb.oneOffs-1) : 0; pb.list.splice( pos, 1 ); } else if ( !nslen ) { if ( pb.list[pos][2] ) { nskeys = KEYS(pb.list[pos][2]); remove_namespaces( pb.namespaces, nskeys, nskeys.length ); } if ( pb.list[pos][1] ) pb.oneOffs = pb.oneOffs > 0 ? (pb.oneOffs-1) : 0; pb.list.splice( pos, 1 ); } } } } } else if ( !hasSubscriber && (nslen > 0) && (pos > 0) ) { while ( --pos >= 0 ) { if ( pb.list[pos][2] && match_namespace( pb.list[pos][2], namespaces, nslen ) ) { nskeys = KEYS(pb.list[pos][2]); remove_namespaces( pb.namespaces, nskeys, nskeys.length ); if ( pb.list[pos][1] ) pb.oneOffs = pb.oneOffs > 0 ? (pb.oneOffs-1) : 0; pb.list.splice( pos, 1 ); } } } else if ( !hasSubscriber && (pos > 0) ) { pb.list = [ ]; pb.oneOffs = 0; pb.namespaces = { }; } } function unsubscribe( seps, pubsub, topic, subscriber ) { if ( pubsub ) { topic = parse_topic( seps, topic ); var t, t2, tags = topic[1].join( OTAG_SEP ), namespaces = topic[2], _topic, _tag, tagslen = tags.length, nslen = namespaces.length, topiclen, hasSubscriber ; topic = topic[0].join( OTOPIC_SEP ); topiclen = topic.length; _topic = topiclen ? 'tp_' + topic : false; _tag = tagslen ? 'tg_' + tags : false; hasSubscriber = !!(subscriber && ("function" === typeof( subscriber ))); if ( !hasSubscriber ) subscriber = null; if ( topiclen && HAS.call(pubsub.topics,_topic) ) { if ( tagslen && HAS.call(pubsub.topics[ _topic ].tags,_tag) ) { remove_subscriber( pubsub.topics[ _topic ].tags[ _tag ], hasSubscriber, subscriber, namespaces, nslen ); if ( !pubsub.topics[ _topic ].tags[ _tag ].list.length ) delete pubsub.topics[ _topic ].tags[ _tag ]; } else if ( !tagslen ) { remove_subscriber( pubsub.topics[ _topic ].notags, hasSubscriber, subscriber, namespaces, nslen ); } if ( !pubsub.topics[ _topic ].notags.list.length && !KEYS(pubsub.topics[ _topic ].tags).length ) delete pubsub.topics[ _topic ]; } else if ( !topiclen && (tagslen || nslen) ) { if ( tagslen ) { if ( HAS.call(pubsub.notopics.tags,_tag) ) { remove_subscriber( pubsub.notopics.tags[ _tag ], hasSubscriber, subscriber, namespaces, nslen ); if ( !pubsub.notopics.tags[ _tag ].list.length ) delete pubsub.notopics.tags[ _tag ]; } // remove from any topics as well for ( t in pubsub.topics ) { if ( HAS.call(pubsub.topics,t) && HAS.call(pubsub.topics[ t ].tags,_tag) ) { remove_subscriber( pubsub.topics[ t ].tags[ _tag ], hasSubscriber, subscriber, namespaces, nslen ); if ( !pubsub.topics[ t ].tags[ _tag ].list.length ) delete pubsub.topics[ t ].tags[ _tag ]; } } } else { remove_subscriber( pubsub.notopics.notags, hasSubscriber, subscriber, namespaces, nslen ); // remove from any tags as well for ( t2 in pubsub.notopics.tags ) { if ( HAS.call(pubsub.notopics.tags,t2) ) { remove_subscriber( pubsub.notopics.tags[ t2 ], hasSubscriber, subscriber, namespaces, nslen ); if ( !pubsub.notopics.tags[ t2 ].list.length ) delete pubsub.notopics.tags[ t2 ]; } } // remove from any topics and tags as well for ( t in pubsub.topics ) { if ( HAS.call(pubsub.topics,t) ) { remove_subscriber( pubsub.topics[ t ].notags, hasSubscriber, subscriber, namespaces, nslen ); for ( t2 in pubsub.topics[ t ].tags ) { if ( HAS.call(pubsub.topics[ t ].tags,t2) ) { remove_subscriber( pubsub.topics[ t ].tags[ t2 ], hasSubscriber, subscriber, namespaces, nslen ); if ( !pubsub.topics[ t ].tags[ t2 ].list.length ) delete pubsub.topics[ t ].tags[ t2 ]; } } } } } } } } // // PublishSubscribe (Interface) var PublishSubscribe = function( ) { if ( !(this instanceof PublishSubscribe) ) return new PublishSubscribe( ); this.initPubSub( ); }; PublishSubscribe.VERSION = __version__; PublishSubscribe.Event = PublishSubscribeEvent; PublishSubscribe.Data = function( props ) { return new PublishSubscribeData(props); }; PublishSubscribe[PROTO] = { constructor: PublishSubscribe ,_seps: null ,_pubsub$: null ,initPubSub: function( ) { var self = this; self._seps = [TOPIC_SEP, TAG_SEP, NS_SEP]; self._pubsub$ = get_pubsub( ); return self; } ,disposePubSub: function( ) { var self = this; self._seps = null; self._pubsub$ = null; return self; } ,setSeparators: function( seps ) { var self = this, l; if ( seps && (l=seps.length) ) { if ( l > 0 && seps[0] ) self._seps[0] = seps[0]; if ( l > 1 && seps[1] ) self._seps[1] = seps[1]; if ( l > 2 && seps[2] ) self._seps[2] = seps[2]; } return self; } ,trigger: function( message, data, delay ) { var self = this; if ( 3 > arguments.length ) delay = 0; delay = +delay; if ( 2 > arguments.length ) data = { }; if ( delay > 0 ) { setTimeout(function( ) { publish( self, self._seps, self._pubsub$, message, data ); }, delay); } else { //console.log(JSON.stringify(self._pubsub$, null, 4)); publish( self, self._seps, self._pubsub$, message, data ); //console.log(JSON.stringify(self._pubsub$, null, 4)); } return self; } ,pipeline: function( message, data, abort, finish, delay ) { var self = this; if ( 5 > arguments.length ) delay = 0; delay = +delay; if ( 2 > arguments.length ) data = { }; if ( delay > 0 ) { setTimeout(function( ) { pipeline( self, self._seps, self._pubsub$, message, data, abort||null, finish||null ); }, delay); } else { //console.log(JSON.stringify(self._pubsub$, null, 4)); pipeline( self, self._seps, self._pubsub$, message, data, abort||null, finish||null ); //console.log(JSON.stringify(self._pubsub$, null, 4)); } return self; } ,on: function( message, callback ) { var self = this; if ( callback && "function" === typeof(callback) ) { //console.log(JSON.stringify(self._pubsub$, null, 4)); subscribe( self._seps, self._pubsub$, message, callback ); //console.log(JSON.stringify(self._pubsub$, null, 4)); } return self; } ,one: function( message, callback ) { var self = this; if ( callback && "function" === typeof(callback) ) { //console.log(JSON.stringify(self._pubsub$, null, 4)); subscribe( self._seps, self._pubsub$, message, callback, true ); //console.log(JSON.stringify(self._pubsub$, null, 4)); } return self; } ,on1: function( message, callback ) { var self = this; if ( callback && "function" === typeof(callback) ) { //console.log(JSON.stringify(self._pubsub$, null, 4)); subscribe( self._seps, self._pubsub$, message, callback, false, true ); //console.log(JSON.stringify(self._pubsub$, null, 4)); } return self; } ,one1: function( message, callback ) { var self = this; if ( callback && "function" === typeof(callback) ) { //console.log(JSON.stringify(self._pubsub$, null, 4)); subscribe( self._seps, self._pubsub$, message, callback, true, true ); //console.log(JSON.stringify(self._pubsub$, null, 4)); } return self; } ,off: function( message, callback ) { var self = this; //console.log(JSON.stringify(self._pubsub$, null, 4)); unsubscribe( self._seps, self._pubsub$, message, callback || null ); //console.log(JSON.stringify(self._pubsub$, null, 4)); return self; } }; // export it return PublishSubscribe; });