mirror of
https://github.com/Hopiu/postal.js.git
synced 2026-03-16 22:20:23 +00:00
Working towards a basic and full build option. Added separate strategies-only build, etc.
This commit is contained in:
parent
c34650abc5
commit
b1e259f9f0
21 changed files with 1500 additions and 723 deletions
24
gulpfile.js
24
gulpfile.js
|
|
@ -35,6 +35,28 @@ gulp.task("combine", function() {
|
|||
.pipe(header(banner, { pkg : pkg }))
|
||||
.pipe(rename("postal.min.js"))
|
||||
.pipe(gulp.dest("./lib/"));
|
||||
|
||||
gulp.src(["./src/postal.basic.js"])
|
||||
.pipe(header(banner, { pkg : pkg }))
|
||||
.pipe(fileImports())
|
||||
.pipe(hintNot())
|
||||
.pipe(beautify({indentSize: 4}))
|
||||
.pipe(gulp.dest("./lib/basic/"))
|
||||
.pipe(uglify({ compress: { negate_iife: false }}))
|
||||
.pipe(header(banner, { pkg : pkg }))
|
||||
.pipe(rename("postal.basic.min.js"))
|
||||
.pipe(gulp.dest("./lib/basic/"));
|
||||
|
||||
gulp.src(["./src/postal.strategies.js"])
|
||||
.pipe(header(banner, { pkg : pkg }))
|
||||
.pipe(fileImports())
|
||||
.pipe(hintNot())
|
||||
.pipe(beautify({indentSize: 4}))
|
||||
.pipe(gulp.dest("./lib/strategies-add-on/"))
|
||||
.pipe(uglify({ compress: { negate_iife: false }}))
|
||||
.pipe(header(banner, { pkg : pkg }))
|
||||
.pipe(rename("postal.strategies.min.js"))
|
||||
.pipe(gulp.dest("./lib/strategies-add-on/"));
|
||||
});
|
||||
|
||||
gulp.task("default", function() {
|
||||
|
|
@ -62,7 +84,7 @@ var createServer = function(port) {
|
|||
var servers;
|
||||
|
||||
gulp.task("server", function(){
|
||||
gulp.run("report");
|
||||
gulp.run("combine", "report");
|
||||
if(!servers) {
|
||||
servers = createServer(port);
|
||||
}
|
||||
|
|
|
|||
417
lib/basic/postal.basic.js
Normal file
417
lib/basic/postal.basic.js
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
/**
|
||||
* postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.
|
||||
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart)
|
||||
* Version: v0.8.11
|
||||
* Url: http://github.com/postaljs/postal.js
|
||||
* License(s): MIT, GPL
|
||||
*/
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof module === "object" && module.exports) {
|
||||
// Node, or CommonJS-Like environments
|
||||
module.exports = factory(require("underscore"), this);
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(["underscore"], function (_) {
|
||||
return factory(_, root);
|
||||
});
|
||||
} else {
|
||||
// Browser globals
|
||||
root.postal = factory(root._, root);
|
||||
}
|
||||
}(this, function (_, global, undefined) {
|
||||
|
||||
var postal;
|
||||
var prevPostal = global.postal;
|
||||
|
||||
var Strategy = function (options) {
|
||||
var _target = options.owner[options.prop];
|
||||
if (typeof _target !== "function") {
|
||||
throw new Error("Strategies can only target methods.");
|
||||
}
|
||||
var _strategies = [];
|
||||
var _context = options.context || options.owner;
|
||||
var strategy = function () {
|
||||
var idx = 0;
|
||||
var next = function next() {
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
var thisIdx = idx;
|
||||
var strategy;
|
||||
idx += 1;
|
||||
if (thisIdx < _strategies.length) {
|
||||
strategy = _strategies[thisIdx];
|
||||
strategy.fn.apply(strategy.context || _context, [next].concat(args));
|
||||
} else {
|
||||
_target.apply(_context, args);
|
||||
}
|
||||
};
|
||||
next.apply(this, arguments);
|
||||
};
|
||||
strategy.target = function () {
|
||||
return _target;
|
||||
};
|
||||
strategy.context = function (ctx) {
|
||||
if (arguments.length === 0) {
|
||||
return _context;
|
||||
} else {
|
||||
_context = ctx;
|
||||
}
|
||||
};
|
||||
strategy.strategies = function () {
|
||||
return _strategies;
|
||||
};
|
||||
strategy.useStrategy = function (strategy) {
|
||||
var idx = 0,
|
||||
exists = false;
|
||||
while (idx < _strategies.length) {
|
||||
if (_strategies[idx].name === strategy.name) {
|
||||
_strategies[idx] = strategy;
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
if (!exists) {
|
||||
_strategies.push(strategy);
|
||||
}
|
||||
};
|
||||
strategy.reset = function () {
|
||||
_strategies = [];
|
||||
};
|
||||
if (options.lazyInit) {
|
||||
_target.useStrategy = function () {
|
||||
options.owner[options.prop] = strategy;
|
||||
strategy.useStrategy.apply(strategy, arguments);
|
||||
};
|
||||
_target.context = function () {
|
||||
options.owner[options.prop] = strategy;
|
||||
return strategy.context.apply(strategy, arguments);
|
||||
};
|
||||
return _target;
|
||||
} else {
|
||||
return strategy;
|
||||
}
|
||||
};
|
||||
|
||||
var ChannelDefinition = function (channelName) {
|
||||
this.channel = channelName || postal.configuration.DEFAULT_CHANNEL;
|
||||
};
|
||||
|
||||
ChannelDefinition.prototype.subscribe = function () {
|
||||
return postal.subscribe(arguments.length === 1 ? new SubscriptionDefinition(this.channel, arguments[0].topic, arguments[0].callback) : new SubscriptionDefinition(this.channel, arguments[0], arguments[1]));
|
||||
};
|
||||
|
||||
ChannelDefinition.prototype.publish = function () {
|
||||
var envelope = arguments.length === 1 ? (Object.prototype.toString.call(arguments[0]) === "[object String]" ? {
|
||||
topic: arguments[0]
|
||||
} : arguments[0]) : {
|
||||
topic: arguments[0],
|
||||
data: arguments[1]
|
||||
};
|
||||
envelope.channel = this.channel;
|
||||
return postal.configuration.bus.publish(envelope);
|
||||
};
|
||||
|
||||
|
||||
var SubscriptionDefinition = function (channel, topic, callback) {
|
||||
if (arguments.length !== 3) {
|
||||
throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");
|
||||
}
|
||||
if (topic.length === 0) {
|
||||
throw new Error("Topics cannot be empty");
|
||||
}
|
||||
this.channel = channel;
|
||||
this.topic = topic;
|
||||
this.subscribe(callback);
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype = {
|
||||
unsubscribe: function () {
|
||||
if (!this.inactive) {
|
||||
this.inactive = true;
|
||||
postal.unsubscribe(this);
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function (callback) {
|
||||
this.callback = callback;
|
||||
this.callback = new Strategy({
|
||||
owner: this,
|
||||
prop: "callback",
|
||||
context: this,
|
||||
// TODO: is this the best option?
|
||||
lazyInit: true
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
withContext: function (context) {
|
||||
this.callback.context(context);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
var bindingsResolver = {
|
||||
cache: {},
|
||||
regex: {},
|
||||
|
||||
compare: function (binding, topic) {
|
||||
var pattern, rgx, prevSegment, result = (this.cache[topic] && this.cache[topic][binding]);
|
||||
if (typeof result !== "undefined") {
|
||||
return result;
|
||||
}
|
||||
if (!(rgx = this.regex[binding])) {
|
||||
pattern = "^" + _.map(binding.split("."), function (segment) {
|
||||
var res = "";
|
||||
if ( !! prevSegment) {
|
||||
res = prevSegment !== "#" ? "\\.\\b" : "\\b";
|
||||
}
|
||||
if (segment === "#") {
|
||||
res += "[\\s\\S]*";
|
||||
} else if (segment === "*") {
|
||||
res += "[^.]+";
|
||||
} else {
|
||||
res += segment;
|
||||
}
|
||||
prevSegment = segment;
|
||||
return res;
|
||||
}).join("") + "$";
|
||||
rgx = this.regex[binding] = new RegExp(pattern);
|
||||
}
|
||||
this.cache[topic] = this.cache[topic] || {};
|
||||
this.cache[topic][binding] = result = rgx.test(topic);
|
||||
return result;
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
this.cache = {};
|
||||
this.regex = {};
|
||||
}
|
||||
};
|
||||
|
||||
var fireSub = function (subDef, envelope) {
|
||||
if (!subDef.inactive && postal.configuration.resolver.compare(subDef.topic, envelope.topic)) {
|
||||
if (_.all(subDef.constraints, function (constraint) {
|
||||
return constraint.call(subDef.context, envelope.data, envelope);
|
||||
})) {
|
||||
if (typeof subDef.callback === "function") {
|
||||
subDef.callback.call(subDef.context, envelope.data, envelope);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var pubInProgress = 0;
|
||||
var unSubQueue = [];
|
||||
var clearUnSubQueue = function () {
|
||||
while (unSubQueue.length) {
|
||||
localBus.unsubscribe(unSubQueue.shift());
|
||||
}
|
||||
};
|
||||
|
||||
var localBus = {
|
||||
addWireTap: function (callback) {
|
||||
var self = this;
|
||||
self.wireTaps.push(callback);
|
||||
return function () {
|
||||
var idx = self.wireTaps.indexOf(callback);
|
||||
if (idx !== -1) {
|
||||
self.wireTaps.splice(idx, 1);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
publish: function (envelope) {
|
||||
++pubInProgress;
|
||||
envelope.timeStamp = new Date();
|
||||
_.each(this.wireTaps, function (tap) {
|
||||
tap(envelope.data, envelope);
|
||||
});
|
||||
if (this.subscriptions[envelope.channel]) {
|
||||
_.each(this.subscriptions[envelope.channel], function (subscribers) {
|
||||
var idx = 0,
|
||||
len = subscribers.length,
|
||||
subDef;
|
||||
while (idx < len) {
|
||||
if (subDef = subscribers[idx++]) {
|
||||
fireSub(subDef, envelope);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (--pubInProgress === 0) {
|
||||
clearUnSubQueue();
|
||||
}
|
||||
return envelope;
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
if (this.subscriptions) {
|
||||
_.each(this.subscriptions, function (channel) {
|
||||
_.each(channel, function (topic) {
|
||||
while (topic.length) {
|
||||
topic.pop().unsubscribe();
|
||||
}
|
||||
});
|
||||
});
|
||||
this.subscriptions = {};
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function (subDef) {
|
||||
var channel = this.subscriptions[subDef.channel],
|
||||
subs;
|
||||
if (!channel) {
|
||||
channel = this.subscriptions[subDef.channel] = {};
|
||||
}
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic];
|
||||
if (!subs) {
|
||||
subs = this.subscriptions[subDef.channel][subDef.topic] = [];
|
||||
}
|
||||
subs.push(subDef);
|
||||
return subDef;
|
||||
},
|
||||
|
||||
subscriptions: {},
|
||||
|
||||
wireTaps: [],
|
||||
|
||||
unsubscribe: function (config) {
|
||||
if (pubInProgress) {
|
||||
unSubQueue.push(config);
|
||||
return;
|
||||
}
|
||||
if (this.subscriptions[config.channel] && this.subscriptions[config.channel][config.topic]) {
|
||||
var len = this.subscriptions[config.channel][config.topic].length,
|
||||
idx = 0;
|
||||
while (idx < len) {
|
||||
if (this.subscriptions[config.channel][config.topic][idx] === config) {
|
||||
this.subscriptions[config.channel][config.topic].splice(idx, 1);
|
||||
break;
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
postal = {
|
||||
configuration: {
|
||||
bus: localBus,
|
||||
resolver: bindingsResolver,
|
||||
DEFAULT_CHANNEL: "/",
|
||||
SYSTEM_CHANNEL: "postal"
|
||||
},
|
||||
|
||||
ChannelDefinition: ChannelDefinition,
|
||||
SubscriptionDefinition: SubscriptionDefinition,
|
||||
|
||||
channel: function (channelName) {
|
||||
return new ChannelDefinition(channelName);
|
||||
},
|
||||
|
||||
subscribe: function (options) {
|
||||
var subDef = new SubscriptionDefinition(options.channel || postal.configuration.DEFAULT_CHANNEL, options.topic, options.callback);
|
||||
postal.configuration.bus.publish({
|
||||
channel: postal.configuration.SYSTEM_CHANNEL,
|
||||
topic: "subscription.created",
|
||||
data: {
|
||||
event: "subscription.created",
|
||||
channel: subDef.channel,
|
||||
topic: subDef.topic
|
||||
}
|
||||
});
|
||||
return postal.configuration.bus.subscribe(subDef);
|
||||
},
|
||||
|
||||
publish: function (envelope) {
|
||||
envelope.channel = envelope.channel || postal.configuration.DEFAULT_CHANNEL;
|
||||
return postal.configuration.bus.publish(envelope);
|
||||
},
|
||||
|
||||
unsubscribe: function (subdef) {
|
||||
postal.configuration.bus.unsubscribe(subdef);
|
||||
postal.configuration.bus.publish({
|
||||
channel: postal.configuration.SYSTEM_CHANNEL,
|
||||
topic: "subscription.removed",
|
||||
data: {
|
||||
event: "subscription.removed",
|
||||
channel: subdef.channel,
|
||||
topic: subdef.topic
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addWireTap: function (callback) {
|
||||
return this.configuration.bus.addWireTap(callback);
|
||||
},
|
||||
|
||||
linkChannels: function (sources, destinations) {
|
||||
var result = [];
|
||||
sources = !_.isArray(sources) ? [sources] : sources;
|
||||
destinations = !_.isArray(destinations) ? [destinations] : destinations;
|
||||
_.each(sources, function (source) {
|
||||
var sourceTopic = source.topic || "#";
|
||||
_.each(destinations, function (destination) {
|
||||
var destChannel = destination.channel || postal.configuration.DEFAULT_CHANNEL;
|
||||
result.push(
|
||||
postal.subscribe({
|
||||
channel: source.channel || postal.configuration.DEFAULT_CHANNEL,
|
||||
topic: sourceTopic,
|
||||
callback: function (data, env) {
|
||||
var newEnv = _.clone(env);
|
||||
newEnv.topic = _.isFunction(destination.topic) ? destination.topic(env.topic) : destination.topic || env.topic;
|
||||
newEnv.channel = destChannel;
|
||||
newEnv.data = data;
|
||||
postal.publish(newEnv);
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
noConflict: function () {
|
||||
if (typeof window === "undefined") {
|
||||
throw new Error("noConflict can only be used in browser clients which aren't using AMD modules");
|
||||
}
|
||||
global.postal = prevPostal;
|
||||
return this;
|
||||
},
|
||||
|
||||
utils: {
|
||||
getSubscribersFor: function () {
|
||||
var channel = arguments[0],
|
||||
tpc = arguments[1];
|
||||
if (arguments.length === 1) {
|
||||
channel = arguments[0].channel || postal.configuration.DEFAULT_CHANNEL;
|
||||
tpc = arguments[0].topic;
|
||||
}
|
||||
if (postal.configuration.bus.subscriptions[channel] && Object.prototype.hasOwnProperty.call(postal.configuration.bus.subscriptions[channel], tpc)) {
|
||||
return postal.configuration.bus.subscriptions[channel][tpc];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
postal.configuration.bus.reset();
|
||||
postal.configuration.resolver.reset();
|
||||
}
|
||||
}
|
||||
};
|
||||
localBus.subscriptions[postal.configuration.SYSTEM_CHANNEL] = {};
|
||||
|
||||
|
||||
if (global && Object.prototype.hasOwnProperty.call(global, "__postalReady__") && _.isArray(global.__postalReady__)) {
|
||||
while (global.__postalReady__.length) {
|
||||
global.__postalReady__.shift().onReady(postal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return postal;
|
||||
}));
|
||||
8
lib/basic/postal.basic.min.js
vendored
Normal file
8
lib/basic/postal.basic.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
291
lib/postal.js
291
lib/postal.js
|
|
@ -24,6 +24,48 @@
|
|||
var postal;
|
||||
var prevPostal = global.postal;
|
||||
|
||||
|
||||
|
||||
var SubscriptionDefinition = function (channel, topic, callback) {
|
||||
if (arguments.length !== 3) {
|
||||
throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");
|
||||
}
|
||||
if (topic.length === 0) {
|
||||
throw new Error("Topics cannot be empty");
|
||||
}
|
||||
this.channel = channel;
|
||||
this.topic = topic;
|
||||
this.subscribe(callback);
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype = {
|
||||
unsubscribe: function () {
|
||||
if (!this.inactive) {
|
||||
this.inactive = true;
|
||||
postal.unsubscribe(this);
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function (callback) {
|
||||
this.callback = callback;
|
||||
this.callback = new Strategy({
|
||||
owner: this,
|
||||
prop: "callback",
|
||||
context: this,
|
||||
// TODO: is this the best option?
|
||||
lazyInit: true
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
withContext: function (context) {
|
||||
this.callback.context(context);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
var Strategy = function (options) {
|
||||
var _target = options.owner[options.prop];
|
||||
if (typeof _target !== "function") {
|
||||
|
|
@ -93,10 +135,46 @@
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
var ConsecutiveDistinctPredicate = function () {
|
||||
var previous;
|
||||
return function (data) {
|
||||
var eq = false;
|
||||
if (_.isString(data)) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual(data, previous);
|
||||
previous = _.clone(data);
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
};
|
||||
|
||||
var DistinctPredicate = function () {
|
||||
var previous = [];
|
||||
return function (data) {
|
||||
var isDistinct = !_.any(previous, function (p) {
|
||||
if (_.isObject(data) || _.isArray(data)) {
|
||||
return _.isEqual(data, p);
|
||||
}
|
||||
return data === p;
|
||||
});
|
||||
if (isDistinct) {
|
||||
previous.push(data);
|
||||
}
|
||||
return isDistinct;
|
||||
};
|
||||
};
|
||||
|
||||
var strats = {
|
||||
setTimeout: function (ms) {
|
||||
withDelay: function (ms) {
|
||||
if (_.isNaN(ms)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "setTimeout",
|
||||
name: "withDelay",
|
||||
fn: function (next, data, envelope) {
|
||||
setTimeout(function () {
|
||||
next(data, envelope);
|
||||
|
|
@ -104,25 +182,37 @@
|
|||
}
|
||||
};
|
||||
},
|
||||
after: function (maxCalls, callback) {
|
||||
defer: function () {
|
||||
return this.withDelay(0);
|
||||
},
|
||||
stopAfter: function (maxCalls, callback) {
|
||||
if (_.isNaN(maxCalls) || maxCalls <= 0) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
var dispose = _.after(maxCalls, callback);
|
||||
return {
|
||||
name: "after",
|
||||
name: "stopAfter",
|
||||
fn: function (next, data, envelope) {
|
||||
dispose();
|
||||
next(data, envelope);
|
||||
}
|
||||
};
|
||||
},
|
||||
throttle: function (ms) {
|
||||
withThrottle: function (ms) {
|
||||
if (_.isNaN(ms)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "throttle",
|
||||
name: "withThrottle",
|
||||
fn: _.throttle(function (next, data, envelope) {
|
||||
next(data, envelope);
|
||||
}, ms)
|
||||
};
|
||||
},
|
||||
debounce: function (ms, immediate) {
|
||||
withDebounce: function (ms, immediate) {
|
||||
if (_.isNaN(ms)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "debounce",
|
||||
fn: _.debounce(function (next, data, envelope) {
|
||||
|
|
@ -130,9 +220,12 @@
|
|||
}, ms, !! immediate)
|
||||
};
|
||||
},
|
||||
predicate: function (pred) {
|
||||
withConstraint: function (pred) {
|
||||
if (!_.isFunction(pred)) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
return {
|
||||
name: "predicate",
|
||||
name: "withConstraint",
|
||||
fn: function (next, data, envelope) {
|
||||
if (pred.call(this, data, envelope)) {
|
||||
next.call(this, data, envelope);
|
||||
|
|
@ -157,37 +250,54 @@
|
|||
}
|
||||
};
|
||||
|
||||
var ConsecutiveDistinctPredicate = function () {
|
||||
var previous;
|
||||
return function (data) {
|
||||
var eq = false;
|
||||
if (_.isString(data)) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual(data, previous);
|
||||
previous = _.clone(data);
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
SubscriptionDefinition.prototype.defer = function () {
|
||||
this.callback.useStrategy(strats.defer());
|
||||
return this;
|
||||
};
|
||||
|
||||
var DistinctPredicate = function () {
|
||||
var previous = [];
|
||||
SubscriptionDefinition.prototype.disposeAfter = function (maxCalls) {
|
||||
var self = this;
|
||||
self.callback.useStrategy(strats.stopAfter(maxCalls, function () {
|
||||
self.unsubscribe.call(self);
|
||||
}));
|
||||
return self;
|
||||
};
|
||||
|
||||
return function (data) {
|
||||
var isDistinct = !_.any(previous, function (p) {
|
||||
if (_.isObject(data) || _.isArray(data)) {
|
||||
return _.isEqual(data, p);
|
||||
}
|
||||
return data === p;
|
||||
});
|
||||
if (isDistinct) {
|
||||
previous.push(data);
|
||||
}
|
||||
return isDistinct;
|
||||
};
|
||||
SubscriptionDefinition.prototype.distinctUntilChanged = function () {
|
||||
this.callback.useStrategy(strats.distinct());
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.distinct = function () {
|
||||
this.callback.useStrategy(strats.distinct({
|
||||
all: true
|
||||
}));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.once = function () {
|
||||
this.disposeAfter(1);
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withConstraint = function (predicate) {
|
||||
this.callback.useStrategy(strats.withConstraint(predicate));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withDebounce = function (milliseconds, immediate) {
|
||||
this.callback.useStrategy(strats.withDebounce(milliseconds, immediate));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withDelay = function (milliseconds) {
|
||||
this.callback.useStrategy(strats.withDelay(milliseconds));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withThrottle = function (milliseconds) {
|
||||
this.callback.useStrategy(strats.withThrottle(milliseconds));
|
||||
return this;
|
||||
};
|
||||
|
||||
var ChannelDefinition = function (channelName) {
|
||||
|
|
@ -209,110 +319,6 @@
|
|||
return postal.configuration.bus.publish(envelope);
|
||||
};
|
||||
|
||||
|
||||
var SubscriptionDefinition = function (channel, topic, callback) {
|
||||
if (arguments.length !== 3) {
|
||||
throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");
|
||||
}
|
||||
if (topic.length === 0) {
|
||||
throw new Error("Topics cannot be empty");
|
||||
}
|
||||
this.channel = channel;
|
||||
this.topic = topic;
|
||||
this.subscribe(callback);
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype = {
|
||||
unsubscribe: function () {
|
||||
if (!this.inactive) {
|
||||
this.inactive = true;
|
||||
postal.unsubscribe(this);
|
||||
}
|
||||
},
|
||||
|
||||
defer: function () {
|
||||
this.callback.useStrategy(postal.configuration.strategies.setTimeout(0));
|
||||
return this;
|
||||
},
|
||||
|
||||
disposeAfter: function (maxCalls) {
|
||||
if (_.isNaN(maxCalls) || maxCalls <= 0) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
var self = this;
|
||||
self.callback.useStrategy(postal.configuration.strategies.after(maxCalls, function () {
|
||||
self.unsubscribe.call(self);
|
||||
}));
|
||||
return self;
|
||||
},
|
||||
|
||||
distinctUntilChanged: function () {
|
||||
this.callback.useStrategy(postal.configuration.strategies.distinct());
|
||||
return this;
|
||||
},
|
||||
|
||||
distinct: function () {
|
||||
this.callback.useStrategy(postal.configuration.strategies.distinct({
|
||||
all: true
|
||||
}));
|
||||
return this;
|
||||
},
|
||||
|
||||
once: function () {
|
||||
this.disposeAfter(1);
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraint: function (predicate) {
|
||||
if (!_.isFunction(predicate)) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.predicate(predicate));
|
||||
return this;
|
||||
},
|
||||
|
||||
withContext: function (context) {
|
||||
this.callback.context(context);
|
||||
return this;
|
||||
},
|
||||
|
||||
withDebounce: function (milliseconds, immediate) {
|
||||
if (_.isNaN(milliseconds)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.debounce(milliseconds, immediate));
|
||||
return this;
|
||||
},
|
||||
|
||||
withDelay: function (milliseconds) {
|
||||
if (_.isNaN(milliseconds)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.setTimeout(milliseconds));
|
||||
return this;
|
||||
},
|
||||
|
||||
withThrottle: function (milliseconds) {
|
||||
if (_.isNaN(milliseconds)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.throttle(milliseconds));
|
||||
return this;
|
||||
},
|
||||
|
||||
subscribe: function (callback) {
|
||||
this.callback = callback;
|
||||
this.callback = new Strategy({
|
||||
owner: this,
|
||||
prop: "callback",
|
||||
context: this,
|
||||
// TODO: is this the best option?
|
||||
lazyInit: true
|
||||
});
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
var bindingsResolver = {
|
||||
cache: {},
|
||||
regex: {},
|
||||
|
|
@ -463,8 +469,7 @@
|
|||
bus: localBus,
|
||||
resolver: bindingsResolver,
|
||||
DEFAULT_CHANNEL: "/",
|
||||
SYSTEM_CHANNEL: "postal",
|
||||
strategies: strats
|
||||
SYSTEM_CHANNEL: "postal"
|
||||
},
|
||||
|
||||
ChannelDefinition: ChannelDefinition,
|
||||
|
|
|
|||
2
lib/postal.min.js
vendored
2
lib/postal.min.js
vendored
File diff suppressed because one or more lines are too long
195
lib/strategies-add-on/postal.strategies.js
Normal file
195
lib/strategies-add-on/postal.strategies.js
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.
|
||||
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart)
|
||||
* Version: v0.8.11
|
||||
* Url: http://github.com/postaljs/postal.js
|
||||
* License(s): MIT, GPL
|
||||
*/
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof module === "object" && module.exports) {
|
||||
// Node, or CommonJS-Like environments
|
||||
module.exports = function (postal) {
|
||||
return factory(postal, this);
|
||||
};
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(["postal"], function (postal) {
|
||||
return factory(postal, root);
|
||||
});
|
||||
} else {
|
||||
// Browser globals
|
||||
root.postal = factory(root.postal, root);
|
||||
}
|
||||
}(this, function (postal, global, undefined) {
|
||||
|
||||
(function (SubscriptionDefinition) {
|
||||
|
||||
|
||||
var ConsecutiveDistinctPredicate = function () {
|
||||
var previous;
|
||||
return function (data) {
|
||||
var eq = false;
|
||||
if (_.isString(data)) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual(data, previous);
|
||||
previous = _.clone(data);
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
};
|
||||
|
||||
var DistinctPredicate = function () {
|
||||
var previous = [];
|
||||
return function (data) {
|
||||
var isDistinct = !_.any(previous, function (p) {
|
||||
if (_.isObject(data) || _.isArray(data)) {
|
||||
return _.isEqual(data, p);
|
||||
}
|
||||
return data === p;
|
||||
});
|
||||
if (isDistinct) {
|
||||
previous.push(data);
|
||||
}
|
||||
return isDistinct;
|
||||
};
|
||||
};
|
||||
|
||||
var strats = {
|
||||
withDelay: function (ms) {
|
||||
if (_.isNaN(ms)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "withDelay",
|
||||
fn: function (next, data, envelope) {
|
||||
setTimeout(function () {
|
||||
next(data, envelope);
|
||||
}, ms);
|
||||
}
|
||||
};
|
||||
},
|
||||
defer: function () {
|
||||
return this.withDelay(0);
|
||||
},
|
||||
stopAfter: function (maxCalls, callback) {
|
||||
if (_.isNaN(maxCalls) || maxCalls <= 0) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
var dispose = _.after(maxCalls, callback);
|
||||
return {
|
||||
name: "stopAfter",
|
||||
fn: function (next, data, envelope) {
|
||||
dispose();
|
||||
next(data, envelope);
|
||||
}
|
||||
};
|
||||
},
|
||||
withThrottle: function (ms) {
|
||||
if (_.isNaN(ms)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "withThrottle",
|
||||
fn: _.throttle(function (next, data, envelope) {
|
||||
next(data, envelope);
|
||||
}, ms)
|
||||
};
|
||||
},
|
||||
withDebounce: function (ms, immediate) {
|
||||
if (_.isNaN(ms)) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "debounce",
|
||||
fn: _.debounce(function (next, data, envelope) {
|
||||
next(data, envelope);
|
||||
}, ms, !! immediate)
|
||||
};
|
||||
},
|
||||
withConstraint: function (pred) {
|
||||
if (!_.isFunction(pred)) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
return {
|
||||
name: "withConstraint",
|
||||
fn: function (next, data, envelope) {
|
||||
if (pred.call(this, data, envelope)) {
|
||||
next.call(this, data, envelope);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
distinct: function (options) {
|
||||
options = options || {};
|
||||
var accessor = function (args) {
|
||||
return args[0];
|
||||
};
|
||||
var check = options.all ? new DistinctPredicate(accessor) : new ConsecutiveDistinctPredicate(accessor);
|
||||
return {
|
||||
name: "distinct",
|
||||
fn: function (next, data, envelope) {
|
||||
if (check(data)) {
|
||||
next(data, envelope);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.defer = function () {
|
||||
this.callback.useStrategy(strats.defer());
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.disposeAfter = function (maxCalls) {
|
||||
var self = this;
|
||||
self.callback.useStrategy(strats.stopAfter(maxCalls, function () {
|
||||
self.unsubscribe.call(self);
|
||||
}));
|
||||
return self;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.distinctUntilChanged = function () {
|
||||
this.callback.useStrategy(strats.distinct());
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.distinct = function () {
|
||||
this.callback.useStrategy(strats.distinct({
|
||||
all: true
|
||||
}));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.once = function () {
|
||||
this.disposeAfter(1);
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withConstraint = function (predicate) {
|
||||
this.callback.useStrategy(strats.withConstraint(predicate));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withDebounce = function (milliseconds, immediate) {
|
||||
this.callback.useStrategy(strats.withDebounce(milliseconds, immediate));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withDelay = function (milliseconds) {
|
||||
this.callback.useStrategy(strats.withDelay(milliseconds));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withThrottle = function (milliseconds) {
|
||||
this.callback.useStrategy(strats.withThrottle(milliseconds));
|
||||
return this;
|
||||
};
|
||||
}(postal.SubscriptionDefinition));
|
||||
|
||||
return postal;
|
||||
}));
|
||||
8
lib/strategies-add-on/postal.strategies.min.js
vendored
Normal file
8
lib/strategies-add-on/postal.strategies.min.js
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.
|
||||
* Author: Jim Cowart (http://freshbrewedcode.com/jimcowart)
|
||||
* Version: v0.8.11
|
||||
* Url: http://github.com/postaljs/postal.js
|
||||
* License(s): MIT, GPL
|
||||
*/
|
||||
(function(t,n){"object"==typeof module&&module.exports?module.exports=function(t){return n(t,this)}:"function"==typeof define&&define.amd?define(["postal"],function(e){return n(e,t)}):t.postal=n(t.postal,t)})(this,function(t){return function(t){var n=function(){var t;return function(n){var e=!1;return _.isString(n)?(e=n===t,t=n):(e=_.isEqual(n,t),t=_.clone(n)),!e}},e=function(){var t=[];return function(n){var e=!_.any(t,function(t){return _.isObject(n)||_.isArray(n)?_.isEqual(n,t):n===t});return e&&t.push(n),e}},i={withDelay:function(t){if(_.isNaN(t))throw"Milliseconds must be a number";return{name:"withDelay",fn:function(n,e,i){setTimeout(function(){n(e,i)},t)}}},defer:function(){return this.withDelay(0)},stopAfter:function(t,n){if(_.isNaN(t)||0>=t)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var e=_.after(t,n);return{name:"stopAfter",fn:function(t,n,i){e(),t(n,i)}}},withThrottle:function(t){if(_.isNaN(t))throw"Milliseconds must be a number";return{name:"withThrottle",fn:_.throttle(function(t,n,e){t(n,e)},t)}},withDebounce:function(t,n){if(_.isNaN(t))throw"Milliseconds must be a number";return{name:"debounce",fn:_.debounce(function(t,n,e){t(n,e)},t,!!n)}},withConstraint:function(t){if(!_.isFunction(t))throw"Predicate constraint must be a function";return{name:"withConstraint",fn:function(n,e,i){t.call(this,e,i)&&n.call(this,e,i)}}},distinct:function(t){t=t||{};var i=function(t){return t[0]},r=t.all?new e(i):new n(i);return{name:"distinct",fn:function(t,n,e){r(n)&&t(n,e)}}}};t.prototype.defer=function(){return this.callback.useStrategy(i.defer()),this},t.prototype.disposeAfter=function(t){var n=this;return n.callback.useStrategy(i.stopAfter(t,function(){n.unsubscribe.call(n)})),n},t.prototype.distinctUntilChanged=function(){return this.callback.useStrategy(i.distinct()),this},t.prototype.distinct=function(){return this.callback.useStrategy(i.distinct({all:!0})),this},t.prototype.once=function(){return this.disposeAfter(1),this},t.prototype.withConstraint=function(t){return this.callback.useStrategy(i.withConstraint(t)),this},t.prototype.withDebounce=function(t,n){return this.callback.useStrategy(i.withDebounce(t,n)),this},t.prototype.withDelay=function(t){return this.callback.useStrategy(i.withDelay(t)),this},t.prototype.withThrottle=function(t){return this.callback.useStrategy(i.withThrottle(t)),this}}(t.SubscriptionDefinition),t});
|
||||
34
spec/basic.html
Normal file
34
spec/basic.html
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../bower/mocha/mocha.css" />
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script type="text/javascript">
|
||||
// initial postal value for a noConflict test....
|
||||
window.postal = { foo: "bar" };
|
||||
</script>
|
||||
<script type="text/javascript" src="../bower/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../bower/underscore/underscore-min.js"></script>
|
||||
<script type="text/javascript" src="../bower/expect/expect.js"></script>
|
||||
<script type="text/javascript" src="../bower/mocha/mocha.js"></script>
|
||||
<script type="text/javascript">
|
||||
mocha.setup({ ui: 'bdd', timeout: 60000 });
|
||||
</script>
|
||||
<script type="text/javascript" src="../lib/postal.js"></script>
|
||||
<script type="text/javascript" src="../lib/strategies-add-on/postal.strategies.js"></script>
|
||||
<script type="text/javascript" src="postaljs.spec.js"></script>
|
||||
<script type="text/javascript" src="utils.spec.js"></script>
|
||||
<script type="text/javascript" src="linkedChannels.spec.js"></script>
|
||||
<script type="text/javascript" src="bindingsResolver.spec.js"></script>
|
||||
<script type="text/javascript" src="channelDefinition.spec.js"></script>
|
||||
<script type="text/javascript" src="subscriptionDefinition.spec.js"></script>
|
||||
<script type="text/javascript">
|
||||
mocha.run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
<script type="text/javascript" src="bindingsResolver.spec.js"></script>
|
||||
<script type="text/javascript" src="channelDefinition.spec.js"></script>
|
||||
<script type="text/javascript" src="subscriptionDefinition.spec.js"></script>
|
||||
<script type="text/javascript" src="subDef.strategies.spec.js"></script>
|
||||
<script type="text/javascript" src="postaljs.strategies.spec.js"></script>
|
||||
<script type="text/javascript">
|
||||
mocha.run();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -70,76 +70,6 @@
|
|||
expect( caughtSubscribeEvent ).to.be.ok();
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing and ignoring duplicates", function () {
|
||||
var subInvokedCnt = 0;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
subInvokedCnt++;
|
||||
} )
|
||||
.distinctUntilChanged();
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
subInvokedCnt = 0;
|
||||
} );
|
||||
it( "callback should be a strategy", function () {
|
||||
expect( typeof postal.configuration.bus.subscriptions.MyChannel.MyTopic[0].callback.context ).to.be( "function" );
|
||||
} );
|
||||
it( "subscription callback should be invoked once", function () {
|
||||
expect( subInvokedCnt ).to.be( 1 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with a disposeAfter of 5", function () {
|
||||
var msgReceivedCnt = 0, subExistsAfter, systemSubscription;
|
||||
before( function () {
|
||||
caughtUnsubscribeEvent = false;
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function () {
|
||||
msgReceivedCnt++;
|
||||
}).disposeAfter( 5 );
|
||||
systemSubscription = postal.subscribe( {
|
||||
channel : "postal",
|
||||
topic : "subscription.*",
|
||||
callback : function ( data, env ) {
|
||||
if ( data.event &&
|
||||
data.event === "subscription.removed" &&
|
||||
data.channel === "MyChannel" &&
|
||||
data.topic === "MyTopic" ) {
|
||||
caughtUnsubscribeEvent = true;
|
||||
}
|
||||
}
|
||||
} );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
subExistsAfter = postal.configuration.bus.subscriptions.MyChannel.MyTopic.length !== 0;
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "subscription callback should be invoked 5 times", function () {
|
||||
expect( msgReceivedCnt ).to.be( 5 );
|
||||
} );
|
||||
it( "subscription should not exist after unsubscribe", function () {
|
||||
expect( subExistsAfter ).to.not.be.ok();
|
||||
} );
|
||||
it( "should have captured unsubscription creation event", function () {
|
||||
expect( caughtUnsubscribeEvent ).to.be.ok();
|
||||
} );
|
||||
it( "postal.getSubscribersFor('MyChannel', 'MyTopic') should not return any subscriptions", function () {
|
||||
expect( postal.utils.getSubscribersFor("MyChannel", "MyTopic").length ).to.be(0);
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with a hierarchical binding, no wildcards", function () {
|
||||
var count = 0, channelB, channelC;
|
||||
before( function () {
|
||||
|
|
@ -221,179 +151,6 @@
|
|||
expect( count ).to.be( 3 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with debounce", function () {
|
||||
var results = [], debouncedChannel;
|
||||
before( function () {
|
||||
debouncedChannel = postal.channel( "DebounceChannel" );
|
||||
subscription = debouncedChannel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( data );
|
||||
} ).withDebounce( 800 );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have only invoked debounced callback once", function ( done ) {
|
||||
debouncedChannel.publish( "MyTopic", 1 ); // starts the two second clock on debounce
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 2 );
|
||||
}, 20 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 3 );
|
||||
}, 80 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 4 );
|
||||
}, 250 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 5 );
|
||||
}, 500 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 6 );
|
||||
}, 1000 ); // should invoke callback
|
||||
setTimeout( function () {
|
||||
expect( results[0] ).to.be( 6 );
|
||||
expect( results.length ).to.be( 1 );
|
||||
done();
|
||||
}, 1900 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with defer", function () {
|
||||
var results = [];
|
||||
before( function () {
|
||||
channel = postal.channel( "DeferChannel" );
|
||||
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have met expected results", function ( done ) {
|
||||
subscription = channel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( "second" );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
done();
|
||||
} ).defer();
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
results.push( "first" );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with delay", function () {
|
||||
var results = [];
|
||||
before( function () {
|
||||
channel = postal.channel( "DelayChannel" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have met expected results", function ( done ) {
|
||||
subscription = channel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( "second" );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
done();
|
||||
} ).withDelay( 500 );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
results.push( "first" );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with once()", function () {
|
||||
var msgReceivedCnt = 0;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic",function ( data ) {
|
||||
msgReceivedCnt++;
|
||||
} ).once();
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "subscription callback should be invoked 1 time", function () {
|
||||
expect( msgReceivedCnt ).to.be( 1 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with multiple constraints returning true", function () {
|
||||
var recvd = false;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
recvd = true;
|
||||
} )
|
||||
.withConstraint(function () {
|
||||
return false;
|
||||
})
|
||||
.withConstraint(function () {
|
||||
return false;
|
||||
})
|
||||
.withConstraint(function () {
|
||||
return true;
|
||||
});
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
recvd = false;
|
||||
} );
|
||||
it( "should overwrite constraint with last one passed in", function () {
|
||||
expect( subscription.callback.strategies().length ).to.be( 1 );
|
||||
} );
|
||||
it( "should have invoked the callback", function () {
|
||||
expect( recvd ).to.be.ok();
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with one constraint returning false", function () {
|
||||
var recvd = false;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
recvd = true;
|
||||
} )
|
||||
.withConstraint( function () {
|
||||
return false;
|
||||
} );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
recvd = false;
|
||||
} );
|
||||
it( "should have a constraint on the subscription", function () {
|
||||
expect( subscription.callback.strategies()[0].name ).to.be( "predicate" );
|
||||
} );
|
||||
it( "should not have invoked the subscription callback", function () {
|
||||
expect( recvd ).to.not.be.ok();
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with one constraint returning true", function () {
|
||||
var recvd = false;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
recvd = true;
|
||||
} )
|
||||
.withConstraint( function () {
|
||||
return true;
|
||||
} );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
recvd = false;
|
||||
} );
|
||||
it( "should have a constraint on the subscription", function () {
|
||||
expect( subscription.callback.strategies()[0].name ).to.be( "predicate" );
|
||||
} );
|
||||
it( "should have invoked the subscription callback", function () {
|
||||
expect( recvd ).to.be.ok();
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with the context being set", function () {
|
||||
var count = 0,
|
||||
obj = {
|
||||
|
|
@ -416,36 +173,6 @@
|
|||
expect( count ).to.be( 1 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with throttle", function () {
|
||||
var results = [], throttledChannel;
|
||||
before( function () {
|
||||
throttledChannel = postal.channel( "ThrottleChannel" );
|
||||
subscription = throttledChannel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( data );
|
||||
} ).withThrottle( 500 );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have only invoked throttled callback twice", function ( done ) {
|
||||
throttledChannel.publish( "MyTopic", 1 ); // starts the two second clock on debounce
|
||||
setTimeout( function () {
|
||||
throttledChannel.publish( "MyTopic", 800 );
|
||||
}, 800 ); // should invoke callback
|
||||
for ( var i = 0; i < 20; i++ ) {
|
||||
(function ( x ) {
|
||||
throttledChannel.publish( "MyTopic", x );
|
||||
})( i );
|
||||
}
|
||||
setTimeout( function () {
|
||||
expect( results[0] ).to.be( 1 );
|
||||
expect( results[2] ).to.be( 800 );
|
||||
expect( results.length ).to.be( 3 );
|
||||
done();
|
||||
}, 1500 );
|
||||
} );
|
||||
} );
|
||||
describe( "When using global subscribe api", function () {
|
||||
before( function () {
|
||||
subscription = postal.subscribe( {
|
||||
|
|
|
|||
288
spec/postaljs.strategies.spec.js
Normal file
288
spec/postaljs.strategies.spec.js
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/* global describe, postal, it, after, before, expect */
|
||||
(function(global) {
|
||||
var postal = typeof window === "undefined" ? require("../lib/postal.js") : window.postal;
|
||||
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||
var _ = typeof window === "undefined" ? require("underscore") : window._;
|
||||
var subscription;
|
||||
var sub;
|
||||
var channel;
|
||||
var caughtSubscribeEvent = false;
|
||||
var caughtUnsubscribeEvent = false;
|
||||
|
||||
describe("Subscription Creation - Strategies", function(){
|
||||
describe( "When subscribing and ignoring duplicates", function () {
|
||||
var subInvokedCnt = 0;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
subInvokedCnt++;
|
||||
} )
|
||||
.distinctUntilChanged();
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
subInvokedCnt = 0;
|
||||
} );
|
||||
it( "callback should be a strategy", function () {
|
||||
expect( typeof postal.configuration.bus.subscriptions.MyChannel.MyTopic[0].callback.context ).to.be( "function" );
|
||||
} );
|
||||
it( "subscription callback should be invoked once", function () {
|
||||
expect( subInvokedCnt ).to.be( 1 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with a disposeAfter of 5", function () {
|
||||
var msgReceivedCnt = 0, subExistsAfter, systemSubscription;
|
||||
before( function () {
|
||||
caughtUnsubscribeEvent = false;
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function () {
|
||||
msgReceivedCnt++;
|
||||
}).disposeAfter( 5 );
|
||||
systemSubscription = postal.subscribe( {
|
||||
channel : "postal",
|
||||
topic : "subscription.*",
|
||||
callback : function ( data, env ) {
|
||||
if ( data.event &&
|
||||
data.event === "subscription.removed" &&
|
||||
data.channel === "MyChannel" &&
|
||||
data.topic === "MyTopic" ) {
|
||||
caughtUnsubscribeEvent = true;
|
||||
}
|
||||
}
|
||||
} );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
subExistsAfter = postal.configuration.bus.subscriptions.MyChannel.MyTopic.length !== 0;
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "subscription callback should be invoked 5 times", function () {
|
||||
expect( msgReceivedCnt ).to.be( 5 );
|
||||
} );
|
||||
it( "subscription should not exist after unsubscribe", function () {
|
||||
expect( subExistsAfter ).to.not.be.ok();
|
||||
} );
|
||||
it( "should have captured unsubscription creation event", function () {
|
||||
expect( caughtUnsubscribeEvent ).to.be.ok();
|
||||
} );
|
||||
it( "postal.getSubscribersFor('MyChannel', 'MyTopic') should not return any subscriptions", function () {
|
||||
expect( postal.utils.getSubscribersFor("MyChannel", "MyTopic").length ).to.be(0);
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with debounce", function () {
|
||||
var results = [], debouncedChannel;
|
||||
before( function () {
|
||||
debouncedChannel = postal.channel( "DebounceChannel" );
|
||||
subscription = debouncedChannel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( data );
|
||||
} ).withDebounce( 800 );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have only invoked debounced callback once", function ( done ) {
|
||||
debouncedChannel.publish( "MyTopic", 1 ); // starts the two second clock on debounce
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 2 );
|
||||
}, 20 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 3 );
|
||||
}, 80 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 4 );
|
||||
}, 250 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 5 );
|
||||
}, 500 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
debouncedChannel.publish( "MyTopic", 6 );
|
||||
}, 1000 ); // should invoke callback
|
||||
setTimeout( function () {
|
||||
expect( results[0] ).to.be( 6 );
|
||||
expect( results.length ).to.be( 1 );
|
||||
done();
|
||||
}, 1900 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with defer", function () {
|
||||
var results = [];
|
||||
before( function () {
|
||||
channel = postal.channel( "DeferChannel" );
|
||||
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have met expected results", function ( done ) {
|
||||
subscription = channel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( "second" );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
done();
|
||||
} ).defer();
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
results.push( "first" );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with delay", function () {
|
||||
var results = [];
|
||||
before( function () {
|
||||
channel = postal.channel( "DelayChannel" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have met expected results", function ( done ) {
|
||||
subscription = channel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( "second" );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
done();
|
||||
} ).withDelay( 500 );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
results.push( "first" );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with once()", function () {
|
||||
var msgReceivedCnt = 0;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic",function ( data ) {
|
||||
msgReceivedCnt++;
|
||||
} ).once();
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "subscription callback should be invoked 1 time", function () {
|
||||
expect( msgReceivedCnt ).to.be( 1 );
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with multiple constraints returning true", function () {
|
||||
var recvd = false;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
recvd = true;
|
||||
} )
|
||||
.withConstraint(function () {
|
||||
return false;
|
||||
})
|
||||
.withConstraint(function () {
|
||||
return false;
|
||||
})
|
||||
.withConstraint(function () {
|
||||
return true;
|
||||
});
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
recvd = false;
|
||||
} );
|
||||
it( "should overwrite constraint with last one passed in", function () {
|
||||
expect( subscription.callback.strategies().length ).to.be( 1 );
|
||||
} );
|
||||
it( "should have invoked the callback", function () {
|
||||
expect( recvd ).to.be.ok();
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with one constraint returning false", function () {
|
||||
var recvd = false;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
recvd = true;
|
||||
} )
|
||||
.withConstraint( function () {
|
||||
return false;
|
||||
} );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
recvd = false;
|
||||
} );
|
||||
it( "should have a constraint on the subscription", function () {
|
||||
expect( subscription.callback.strategies()[0].name ).to.be( "withConstraint" );
|
||||
} );
|
||||
it( "should not have invoked the subscription callback", function () {
|
||||
expect( recvd ).to.not.be.ok();
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with one constraint returning true", function () {
|
||||
var recvd = false;
|
||||
before( function () {
|
||||
channel = postal.channel( "MyChannel" );
|
||||
subscription = channel.subscribe( "MyTopic", function ( data ) {
|
||||
recvd = true;
|
||||
} )
|
||||
.withConstraint( function () {
|
||||
return true;
|
||||
} );
|
||||
channel.publish( "MyTopic", "Testing123" );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
recvd = false;
|
||||
} );
|
||||
it( "should have a constraint on the subscription", function () {
|
||||
expect( subscription.callback.strategies()[0].name ).to.be( "withConstraint" );
|
||||
} );
|
||||
it( "should have invoked the subscription callback", function () {
|
||||
expect( recvd ).to.be.ok();
|
||||
} );
|
||||
} );
|
||||
describe( "When subscribing with throttle", function () {
|
||||
var results = [], throttledChannel;
|
||||
before( function () {
|
||||
throttledChannel = postal.channel( "ThrottleChannel" );
|
||||
subscription = throttledChannel.subscribe( "MyTopic",
|
||||
function ( data ) {
|
||||
results.push( data );
|
||||
} ).withThrottle( 500 );
|
||||
} );
|
||||
after( function () {
|
||||
postal.utils.reset();
|
||||
} );
|
||||
it( "should have only invoked throttled callback twice", function ( done ) {
|
||||
throttledChannel.publish( "MyTopic", 1 ); // starts the two second clock on debounce
|
||||
setTimeout( function () {
|
||||
throttledChannel.publish( "MyTopic", 800 );
|
||||
}, 800 ); // should invoke callback
|
||||
for ( var i = 0; i < 20; i++ ) {
|
||||
(function ( x ) {
|
||||
throttledChannel.publish( "MyTopic", x );
|
||||
})( i );
|
||||
}
|
||||
setTimeout( function () {
|
||||
expect( results[0] ).to.be( 1 );
|
||||
expect( results[2] ).to.be( 800 );
|
||||
expect( results.length ).to.be( 3 );
|
||||
done();
|
||||
}, 1500 );
|
||||
} );
|
||||
} );
|
||||
});
|
||||
|
||||
}(this));
|
||||
197
spec/subDef.strategies.spec.js
Normal file
197
spec/subDef.strategies.spec.js
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/* global describe, postal, it, after, before, expect */
|
||||
(function() {
|
||||
var postal = typeof window === "undefined" ? require("../lib/postal.js") : window.postal;
|
||||
var expect = typeof window === "undefined" ? require("expect.js") : window.expect;
|
||||
var NO_OP = function () {};
|
||||
var SubscriptionDefinition = postal.SubscriptionDefinition;
|
||||
describe( "SubscriptionDefinition - Strategies", function () {
|
||||
|
||||
describe( "When setting distinctUntilChanged", function () {
|
||||
var sDefa = new SubscriptionDefinition( "TestChannel", "TestTopic", NO_OP ).distinctUntilChanged();
|
||||
|
||||
it( "callback should be a strategy", function () {
|
||||
expect( typeof sDefa.callback.context ).to.be( "function" );
|
||||
});
|
||||
} );
|
||||
|
||||
describe( "When adding a constraint", function () {
|
||||
var sDefb = new SubscriptionDefinition( "TestChannel", "TestTopic", NO_OP ).withConstraint( function () {
|
||||
});
|
||||
|
||||
it( "callback should be a strategy", function () {
|
||||
expect( typeof sDefb.callback.context ).to.be( "function" );
|
||||
});
|
||||
} );
|
||||
|
||||
describe( "When deferring the callback", function () {
|
||||
var results = [], sDefe;
|
||||
|
||||
it( "Should defer the callback", function ( done ) {
|
||||
sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) {
|
||||
results.push( data );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
expect( env.topic ).to.be( "TestTopic" );
|
||||
done();
|
||||
} ).defer();
|
||||
|
||||
sDefe.callback( "second", { topic : "TestTopic" } );
|
||||
results.push( "first" );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var context = {
|
||||
key : 1234
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext(context).defer();
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact when modified later", function ( done ) {
|
||||
var context = {
|
||||
key : 1234
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).defer().withContext(context);
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "When throttling the callback", function () {
|
||||
|
||||
it( "should have only invoked throttled callback twice", function ( done ) {
|
||||
var results = [], timeout1, timeout2;
|
||||
var sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function ( data ) {
|
||||
results.push( data );
|
||||
} ).withThrottle( 1200, { leading: true } );
|
||||
sDefe.callback( 1 ); // starts the clock on throttle
|
||||
timeout1 = setTimeout( function () {
|
||||
sDefe.callback( 700 );
|
||||
}, 700 ); // should invoke callback
|
||||
for ( var i = 0; i < 20; i++ ) {
|
||||
(function ( x ) {
|
||||
sDefe.callback( x );
|
||||
})( i );
|
||||
}
|
||||
timeout2 = setTimeout( function () {
|
||||
expect( results[0] ).to.be( 1 );
|
||||
expect( results.length ).to.be( 2 );
|
||||
done();
|
||||
}, 1500 );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function( done ) {
|
||||
var results = [], timeout1, timeout2;
|
||||
var sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function ( data ) {
|
||||
results.push( data );
|
||||
} ).withThrottle( 1000, { leading: true } );
|
||||
var context = {
|
||||
key : 'abcd'
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext( context ).withThrottle( 500 );
|
||||
|
||||
sDefe.callback.call( sDefe.context, 1 );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "When delaying the callback", function () {
|
||||
var results = [], sDefe;
|
||||
|
||||
it( "Should delay the callback", function ( done ) {
|
||||
sDefe = new SubscriptionDefinition( "DelayTest", "TestTopic", function ( data, env ) {
|
||||
results.push( data );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
expect( env.topic ).to.be( "TestTopic" );
|
||||
done();
|
||||
} ).withDelay( 200 );
|
||||
sDefe.callback( "second", { topic : "TestTopic" } );
|
||||
results.push( "first" );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var context = {
|
||||
key : 1234
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "DelayTest", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext(context).withDelay( 200 );
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "When debouncing the callback", function () {
|
||||
var results = [],
|
||||
sDefe = new SubscriptionDefinition( "DebounceTest", "TestTopic", function ( data ) {
|
||||
results.push( data );
|
||||
} ).withDebounce( 800 );
|
||||
|
||||
it( "should have only invoked debounced callback once", function ( done ) {
|
||||
sDefe.callback( 1 ); // starts the two second clock on debounce
|
||||
setTimeout( function () {
|
||||
sDefe.callback( 2 );
|
||||
}, 20 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
sDefe.callback( 3 );
|
||||
}, 80 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
sDefe.callback( 6 );
|
||||
}, 800 ); // should invoke callback
|
||||
setTimeout( function () {
|
||||
expect( results[0] ).to.be( 6 );
|
||||
expect( results.length ).to.be( 1 );
|
||||
done();
|
||||
}, 1800 );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var context = {
|
||||
key : 5678
|
||||
};
|
||||
var timeout;
|
||||
sDefe = new SubscriptionDefinition( "DebounceTest", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
clearTimeout(timeout);
|
||||
done();
|
||||
} ).withContext(context).withDebounce( 100 );
|
||||
|
||||
sDefe.callback.call( sDefe.context, 1 );
|
||||
timeout = setTimeout( function () {
|
||||
sDefe.callback.call( sDefe.context, 2 );
|
||||
}, 200 ); // should invoke callback
|
||||
});
|
||||
} );
|
||||
|
||||
describe( "When self disposing", function () {
|
||||
var context = {
|
||||
key : 'abcd'
|
||||
};
|
||||
|
||||
it( "Should be inactive", function () {
|
||||
var sDefe = new SubscriptionDefinition( "DisposeTest", "TestTopic", function ( data, env ) {
|
||||
} ).withContext(context).disposeAfter( 1 );
|
||||
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
|
||||
expect( sDefe.inactive ).to.be( true );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var sDefe = new SubscriptionDefinition( "DisposeTest", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext(context).disposeAfter( 200 );
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
}());
|
||||
|
|
@ -27,23 +27,6 @@
|
|||
} );
|
||||
} );
|
||||
|
||||
describe( "When setting distinctUntilChanged", function () {
|
||||
var sDefa = new SubscriptionDefinition( "TestChannel", "TestTopic", NO_OP ).distinctUntilChanged();
|
||||
|
||||
it( "callback should be a strategy", function () {
|
||||
expect( typeof sDefa.callback.context ).to.be( "function" );
|
||||
});
|
||||
} );
|
||||
|
||||
describe( "When adding a constraint", function () {
|
||||
var sDefb = new SubscriptionDefinition( "TestChannel", "TestTopic", NO_OP ).withConstraint( function () {
|
||||
});
|
||||
|
||||
it( "callback should be a strategy", function () {
|
||||
expect( typeof sDefb.callback.context ).to.be( "function" );
|
||||
});
|
||||
} );
|
||||
|
||||
describe( "When setting the context", function () {
|
||||
var obj = { name : "Rose" },
|
||||
name,
|
||||
|
|
@ -72,176 +55,5 @@
|
|||
expect( sDefe.callback ).to.be( fn );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "When deferring the callback", function () {
|
||||
var results = [], sDefe;
|
||||
|
||||
it( "Should defer the callback", function ( done ) {
|
||||
sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) {
|
||||
results.push( data );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
expect( env.topic ).to.be( "TestTopic" );
|
||||
done();
|
||||
} ).defer();
|
||||
|
||||
sDefe.callback( "second", { topic : "TestTopic" } );
|
||||
results.push( "first" );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var context = {
|
||||
key : 1234
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext(context).defer();
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact when modified later", function ( done ) {
|
||||
var context = {
|
||||
key : 1234
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).defer().withContext(context);
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "When throttling the callback", function () {
|
||||
|
||||
it( "should have only invoked throttled callback twice", function ( done ) {
|
||||
var results = [], timeout1, timeout2;
|
||||
var sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function ( data ) {
|
||||
results.push( data );
|
||||
} ).withThrottle( 1200, { leading: true } );
|
||||
sDefe.callback( 1 ); // starts the clock on throttle
|
||||
timeout1 = setTimeout( function () {
|
||||
sDefe.callback( 700 );
|
||||
}, 700 ); // should invoke callback
|
||||
for ( var i = 0; i < 20; i++ ) {
|
||||
(function ( x ) {
|
||||
sDefe.callback( x );
|
||||
})( i );
|
||||
}
|
||||
timeout2 = setTimeout( function () {
|
||||
expect( results[0] ).to.be( 1 );
|
||||
expect( results.length ).to.be( 2 );
|
||||
done();
|
||||
}, 1500 );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function( done ) {
|
||||
var results = [], timeout1, timeout2;
|
||||
var sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function ( data ) {
|
||||
results.push( data );
|
||||
} ).withThrottle( 1000, { leading: true } );
|
||||
var context = {
|
||||
key : 'abcd'
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "ThrottleTest", "TestTopic", function( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext( context ).withThrottle( 500 );
|
||||
|
||||
sDefe.callback.call( sDefe.context, 1 );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "When delaying the callback", function () {
|
||||
var results = [], sDefe;
|
||||
|
||||
it( "Should delay the callback", function ( done ) {
|
||||
sDefe = new SubscriptionDefinition( "DelayTest", "TestTopic", function ( data, env ) {
|
||||
results.push( data );
|
||||
expect( results[0] ).to.be( "first" );
|
||||
expect( results[1] ).to.be( "second" );
|
||||
expect( env.topic ).to.be( "TestTopic" );
|
||||
done();
|
||||
} ).withDelay( 200 );
|
||||
sDefe.callback( "second", { topic : "TestTopic" } );
|
||||
results.push( "first" );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var context = {
|
||||
key : 1234
|
||||
};
|
||||
sDefe = new SubscriptionDefinition( "DelayTest", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext(context).withDelay( 200 );
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "When debouncing the callback", function () {
|
||||
var results = [],
|
||||
sDefe = new SubscriptionDefinition( "DebounceTest", "TestTopic", function ( data ) {
|
||||
results.push( data );
|
||||
} ).withDebounce( 800 );
|
||||
|
||||
it( "should have only invoked debounced callback once", function ( done ) {
|
||||
sDefe.callback( 1 ); // starts the two second clock on debounce
|
||||
setTimeout( function () {
|
||||
sDefe.callback( 2 );
|
||||
}, 20 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
sDefe.callback( 3 );
|
||||
}, 80 ); // should not invoke callback
|
||||
setTimeout( function () {
|
||||
sDefe.callback( 6 );
|
||||
}, 800 ); // should invoke callback
|
||||
setTimeout( function () {
|
||||
expect( results[0] ).to.be( 6 );
|
||||
expect( results.length ).to.be( 1 );
|
||||
done();
|
||||
}, 1800 );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var context = {
|
||||
key : 5678
|
||||
};
|
||||
var timeout;
|
||||
sDefe = new SubscriptionDefinition( "DebounceTest", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
clearTimeout(timeout);
|
||||
done();
|
||||
} ).withContext(context).withDebounce( 100 );
|
||||
|
||||
sDefe.callback.call( sDefe.context, 1 );
|
||||
timeout = setTimeout( function () {
|
||||
sDefe.callback.call( sDefe.context, 2 );
|
||||
}, 200 ); // should invoke callback
|
||||
});
|
||||
} );
|
||||
|
||||
describe( "When self disposing", function () {
|
||||
var context = {
|
||||
key : 'abcd'
|
||||
};
|
||||
|
||||
it( "Should be inactive", function () {
|
||||
var sDefe = new SubscriptionDefinition( "DisposeTest", "TestTopic", function ( data, env ) {
|
||||
} ).withContext(context).disposeAfter( 1 );
|
||||
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
|
||||
expect( sDefe.inactive ).to.be( true );
|
||||
} );
|
||||
|
||||
it( "Should keep the context intact", function ( done ) {
|
||||
var sDefe = new SubscriptionDefinition( "DisposeTest", "TestTopic", function ( data, env ) {
|
||||
expect( this ).to.be( context );
|
||||
done();
|
||||
} ).withContext(context).disposeAfter( 200 );
|
||||
sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
}());
|
||||
|
|
@ -5,8 +5,7 @@ postal = {
|
|||
bus : localBus,
|
||||
resolver : bindingsResolver,
|
||||
DEFAULT_CHANNEL : "/",
|
||||
SYSTEM_CHANNEL : "postal",
|
||||
strategies : strats
|
||||
SYSTEM_CHANNEL : "postal"
|
||||
},
|
||||
|
||||
ChannelDefinition : ChannelDefinition,
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
/*jshint -W098 */
|
||||
var ConsecutiveDistinctPredicate = function () {
|
||||
var previous;
|
||||
return function ( data ) {
|
||||
var eq = false;
|
||||
if ( _.isString( data ) ) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual( data, previous );
|
||||
previous = _.clone( data );
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/*jshint -W098 */
|
||||
var DistinctPredicate = function () {
|
||||
var previous = [];
|
||||
|
||||
return function ( data ) {
|
||||
var isDistinct = !_.any( previous, function ( p ) {
|
||||
if ( _.isObject( data ) || _.isArray( data ) ) {
|
||||
return _.isEqual( data, p );
|
||||
}
|
||||
return data === p;
|
||||
} );
|
||||
if ( isDistinct ) {
|
||||
previous.push( data );
|
||||
}
|
||||
return isDistinct;
|
||||
};
|
||||
};
|
||||
|
|
@ -20,74 +20,6 @@ SubscriptionDefinition.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
defer : function () {
|
||||
this.callback.useStrategy(postal.configuration.strategies.setTimeout(0));
|
||||
return this;
|
||||
},
|
||||
|
||||
disposeAfter : function ( maxCalls ) {
|
||||
if ( _.isNaN( maxCalls ) || maxCalls <= 0 ) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
var self = this;
|
||||
self.callback.useStrategy(postal.configuration.strategies.after(maxCalls, function() {
|
||||
self.unsubscribe.call(self);
|
||||
}));
|
||||
return self;
|
||||
},
|
||||
|
||||
distinctUntilChanged : function () {
|
||||
this.callback.useStrategy(postal.configuration.strategies.distinct());
|
||||
return this;
|
||||
},
|
||||
|
||||
distinct : function () {
|
||||
this.callback.useStrategy(postal.configuration.strategies.distinct({ all: true }));
|
||||
return this;
|
||||
},
|
||||
|
||||
once : function () {
|
||||
this.disposeAfter( 1 );
|
||||
return this;
|
||||
},
|
||||
|
||||
withConstraint : function ( predicate ) {
|
||||
if ( !_.isFunction( predicate ) ) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.predicate(predicate));
|
||||
return this;
|
||||
},
|
||||
|
||||
withContext : function ( context ) {
|
||||
this.callback.context(context);
|
||||
return this;
|
||||
},
|
||||
|
||||
withDebounce : function ( milliseconds, immediate ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.debounce(milliseconds, immediate));
|
||||
return this;
|
||||
},
|
||||
|
||||
withDelay : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.setTimeout(milliseconds));
|
||||
return this;
|
||||
},
|
||||
|
||||
withThrottle : function ( milliseconds ) {
|
||||
if ( _.isNaN( milliseconds ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
this.callback.useStrategy(postal.configuration.strategies.throttle(milliseconds));
|
||||
return this;
|
||||
},
|
||||
|
||||
subscribe : function ( callback ) {
|
||||
this.callback = callback;
|
||||
this.callback = new Strategy({
|
||||
|
|
@ -97,5 +29,12 @@ SubscriptionDefinition.prototype = {
|
|||
lazyInit : true
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
withContext : function ( context ) {
|
||||
this.callback.context(context);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
36
src/postal.basic.js
Normal file
36
src/postal.basic.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*jshint -W098 */
|
||||
(function ( root, factory ) {
|
||||
if ( typeof module === "object" && module.exports ) {
|
||||
// Node, or CommonJS-Like environments
|
||||
module.exports = factory( require( "underscore" ), this );
|
||||
} else if ( typeof define === "function" && define.amd ) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define( ["underscore"], function ( _ ) {
|
||||
return factory( _, root );
|
||||
} );
|
||||
} else {
|
||||
// Browser globals
|
||||
root.postal = factory( root._, root );
|
||||
}
|
||||
}( this, function ( _, global, undefined ) {
|
||||
|
||||
var postal;
|
||||
var prevPostal = global.postal;
|
||||
|
||||
//import("strategy.js");
|
||||
//import("ChannelDefinition.js");
|
||||
//import("SubscriptionDefinition.js");
|
||||
//import("AmqpBindingsResolver.js");
|
||||
//import("LocalBus.js");
|
||||
//import("Api.js");
|
||||
|
||||
/*jshint -W106 */
|
||||
if ( global && Object.prototype.hasOwnProperty.call( global, "__postalReady__" ) && _.isArray( global.__postalReady__ ) ) {
|
||||
while(global.__postalReady__.length) {
|
||||
global.__postalReady__.shift().onReady(postal);
|
||||
}
|
||||
}
|
||||
/*jshint +W106 */
|
||||
|
||||
return postal;
|
||||
} ));
|
||||
|
|
@ -17,12 +17,10 @@
|
|||
var postal;
|
||||
var prevPostal = global.postal;
|
||||
|
||||
//import("SubscriptionDefinition.js");
|
||||
//import("strategy.js");
|
||||
//import("strategies.js");
|
||||
//import("ConsecutiveDistinctPredicate.js");
|
||||
//import("DistinctPredicate.js");
|
||||
//import("ChannelDefinition.js");
|
||||
//import("SubscriptionDefinition.js");
|
||||
//import("AmqpBindingsResolver.js");
|
||||
//import("LocalBus.js");
|
||||
//import("Api.js");
|
||||
|
|
|
|||
24
src/postal.strategies.js
Normal file
24
src/postal.strategies.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*jshint -W098 */
|
||||
(function ( root, factory ) {
|
||||
if ( typeof module === "object" && module.exports ) {
|
||||
// Node, or CommonJS-Like environments
|
||||
module.exports = function(postal) {
|
||||
return factory( postal, this );
|
||||
};
|
||||
} else if ( typeof define === "function" && define.amd ) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define( ["postal"], function ( postal ) {
|
||||
return factory( postal, root );
|
||||
} );
|
||||
} else {
|
||||
// Browser globals
|
||||
root.postal = factory( root.postal, root );
|
||||
}
|
||||
}( this, function ( postal, global, undefined ) {
|
||||
|
||||
(function(SubscriptionDefinition) {
|
||||
//import("strategies.js");
|
||||
}(postal.SubscriptionDefinition));
|
||||
|
||||
return postal;
|
||||
} ));
|
||||
|
|
@ -1,8 +1,44 @@
|
|||
/* global DistinctPredicate,ConsecutiveDistinctPredicate */
|
||||
/* global DistinctPredicate,ConsecutiveDistinctPredicate,SubscriptionDefinition,postal */
|
||||
/*jshint -W098 */
|
||||
var ConsecutiveDistinctPredicate = function () {
|
||||
var previous;
|
||||
return function ( data ) {
|
||||
var eq = false;
|
||||
if ( _.isString( data ) ) {
|
||||
eq = data === previous;
|
||||
previous = data;
|
||||
}
|
||||
else {
|
||||
eq = _.isEqual( data, previous );
|
||||
previous = _.clone( data );
|
||||
}
|
||||
return !eq;
|
||||
};
|
||||
};
|
||||
|
||||
var DistinctPredicate = function () {
|
||||
var previous = [];
|
||||
return function ( data ) {
|
||||
var isDistinct = !_.any( previous, function ( p ) {
|
||||
if ( _.isObject( data ) || _.isArray( data ) ) {
|
||||
return _.isEqual( data, p );
|
||||
}
|
||||
return data === p;
|
||||
} );
|
||||
if ( isDistinct ) {
|
||||
previous.push( data );
|
||||
}
|
||||
return isDistinct;
|
||||
};
|
||||
};
|
||||
|
||||
var strats = {
|
||||
setTimeout: function(ms) {
|
||||
withDelay: function(ms) {
|
||||
if ( _.isNaN( ms ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "setTimeout",
|
||||
name: "withDelay",
|
||||
fn: function (next, data, envelope) {
|
||||
setTimeout(function () {
|
||||
next(data, envelope);
|
||||
|
|
@ -10,25 +46,37 @@ var strats = {
|
|||
}
|
||||
};
|
||||
},
|
||||
after: function(maxCalls, callback) {
|
||||
defer: function() {
|
||||
return this.withDelay(0);
|
||||
},
|
||||
stopAfter: function(maxCalls, callback) {
|
||||
if ( _.isNaN( maxCalls ) || maxCalls <= 0 ) {
|
||||
throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero.";
|
||||
}
|
||||
var dispose = _.after(maxCalls, callback);
|
||||
return {
|
||||
name: "after",
|
||||
name: "stopAfter",
|
||||
fn: function (next, data, envelope) {
|
||||
dispose();
|
||||
next(data, envelope);
|
||||
}
|
||||
};
|
||||
},
|
||||
throttle : function(ms) {
|
||||
withThrottle : function(ms) {
|
||||
if ( _.isNaN( ms ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "throttle",
|
||||
name: "withThrottle",
|
||||
fn: _.throttle(function(next, data, envelope) {
|
||||
next(data, envelope);
|
||||
}, ms)
|
||||
};
|
||||
},
|
||||
debounce: function(ms, immediate) {
|
||||
withDebounce: function(ms, immediate) {
|
||||
if ( _.isNaN( ms ) ) {
|
||||
throw "Milliseconds must be a number";
|
||||
}
|
||||
return {
|
||||
name: "debounce",
|
||||
fn: _.debounce(function(next, data, envelope) {
|
||||
|
|
@ -36,9 +84,12 @@ var strats = {
|
|||
}, ms, !!immediate)
|
||||
};
|
||||
},
|
||||
predicate: function(pred) {
|
||||
withConstraint: function(pred) {
|
||||
if ( !_.isFunction( pred ) ) {
|
||||
throw "Predicate constraint must be a function";
|
||||
}
|
||||
return {
|
||||
name: "predicate",
|
||||
name: "withConstraint",
|
||||
fn: function(next, data, envelope) {
|
||||
if(pred.call(this, data, envelope)) {
|
||||
next.call(this, data, envelope);
|
||||
|
|
@ -63,4 +114,52 @@ var strats = {
|
|||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.defer = function () {
|
||||
this.callback.useStrategy(strats.defer());
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.disposeAfter = function ( maxCalls ) {
|
||||
var self = this;
|
||||
self.callback.useStrategy(strats.stopAfter(maxCalls, function() {
|
||||
self.unsubscribe.call(self);
|
||||
}));
|
||||
return self;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.distinctUntilChanged = function () {
|
||||
this.callback.useStrategy(strats.distinct());
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.distinct = function () {
|
||||
this.callback.useStrategy(strats.distinct({ all : true }));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.once = function () {
|
||||
this.disposeAfter(1);
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withConstraint = function ( predicate ) {
|
||||
this.callback.useStrategy(strats.withConstraint(predicate));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withDebounce = function ( milliseconds, immediate ) {
|
||||
this.callback.useStrategy(strats.withDebounce(milliseconds, immediate));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withDelay = function ( milliseconds ) {
|
||||
this.callback.useStrategy(strats.withDelay(milliseconds));
|
||||
return this;
|
||||
};
|
||||
|
||||
SubscriptionDefinition.prototype.withThrottle = function ( milliseconds ) {
|
||||
this.callback.useStrategy(strats.withThrottle(milliseconds));
|
||||
return this;
|
||||
};
|
||||
Loading…
Reference in a new issue