bal-util
Version:
Common utility functions for Node.js used and maintained by Benjamin Lupton
387 lines (332 loc) • 11 kB
JavaScript
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// Generated by CoffeeScript 2.3.1
// Import
var Event, EventEmitter, EventSystem, typeChecker;
var _require = require('events');
EventEmitter = _require.EventEmitter;
typeChecker = require('typechecker');
Event = function () {
// =====================================
// Event & EventSystem
// Extends the EventEmitterEnhanced with support for:
// - blocking events
// - start and finish events
// Event
var Event =
// Apply our name on construction
function Event(_ref) {
var name = _ref.name;
_classCallCheck(this, Event);
this.name = name;
};
;
// The name of the event
Event.prototype.name = null;
// Is the event currently locked?
Event.prototype.locked = false;
// Has the event finished running?
Event.prototype.finished = false;
return Event;
}.call(undefined);
EventSystem = function () {
// EventSystem
var EventSystem = function (_EventEmitter) {
_inherits(EventSystem, _EventEmitter);
function EventSystem() {
_classCallCheck(this, EventSystem);
return _possibleConstructorReturn(this, (EventSystem.__proto__ || Object.getPrototypeOf(EventSystem)).apply(this, arguments));
}
_createClass(EventSystem, [{
key: 'event',
// Fetch the event object for the event
value: function event(eventName) {
var base;
// Prepare
this._eventSystemEvents || (this._eventSystemEvents = {});
// Return the fetched event, create it if it doesn't exist already
return (base = this._eventSystemEvents)[eventName] || (base[eventName] = new Event(eventName));
}
// Lock the event
// next(err)
}, {
key: 'lock',
value: function lock(eventName, next) {
var _this2 = this;
var err, event;
// Grab the event
event = this.event(eventName);
// Grab a lock on the event
if (event.locked === false) {
// Place the lock
event.locked = true;
try {
// Trigger our event
// then fire our callback
this.emit(eventName + ':locked');
} catch (error) {
err = error;
next(err);
return this;
} finally {
next();
}
} else {
// Wait until the current task has finished
this.onceUnlocked(eventName, function (err) {
if (err) {
return next(err);
}
// Then try again
return _this2.lock(eventName, next);
});
}
return this;
}
// Unlock the event
// next(err)
}, {
key: 'unlock',
value: function unlock(eventName, next) {
var err, event;
// Grab the event
event = this.event(eventName);
// Release the lock
event.locked = false;
try {
// Trigger our event
// then fire our callback
this.emit(eventName + ':unlocked');
} catch (error) {
err = error;
next(err);
return this;
} finally {
next();
}
return this;
}
// Start our event
// 1. Performs a lock
// 2. Sets event's finished flag to false
// 3. Fires callback
// next(err)
}, {
key: 'start',
value: function start(eventName, next) {
var _this3 = this;
// Grab a locak
this.lock(eventName, function (err) {
var event;
if (err) {
// Error?
return next(err);
}
// Grab the event
event = _this3.event(eventName);
// Set as started
event.finished = false;
try {
// Trigger our event
// then fire our callback
return _this3.emit(eventName + ':started');
} catch (error) {
err = error;
next(err);
return _this3;
} finally {
next();
}
});
return this;
}
// Finish, alias for finished
}, {
key: 'finish',
value: function finish() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return this.finished.apply(this, args);
}
// Finished our event
// 1. Sets event's finished flag to true
// 2. Unlocks the event
// 3. Fires callback
// next(err)
}, {
key: 'finished',
value: function finished(eventName, next) {
var _this4 = this;
var event;
// Grab the event
event = this.event(eventName);
// Set as finished
event.finished = true;
// Unlock
this.unlock(eventName, function (err) {
if (err) {
// Error?
return next(err);
}
try {
// Trigger our event
// then fire our callback
return _this4.emit(eventName + ':finished');
} catch (error) {
err = error;
next(err);
return _this4;
} finally {
next();
}
});
return this;
}
// Run one time once an event has unlocked
// next(err)
}, {
key: 'onceUnlocked',
value: function onceUnlocked(eventName, next) {
var event;
// Grab the event
event = this.event(eventName);
// Check lock status
if (event.locked) {
// Wait until our event has unlocked to fire the callback
this.once(eventName + ':unlocked', next);
} else {
// Fire our callback now
next();
}
return this;
}
// Run one time once an event has finished
// next(err)
}, {
key: 'onceFinished',
value: function onceFinished(eventName, next) {
var event;
// Grab the event
event = this.event(eventName);
// Check finish status
if (event.finished) {
// Fire our callback now
next();
} else {
// Wait until our event has finished to fire the callback
this.once(eventName + ':finished', next);
}
return this;
}
// Run every time an event has finished
// next(err)
}, {
key: 'whenFinished',
value: function whenFinished(eventName, next) {
var event;
// Grab the event
event = this.event(eventName);
// Check finish status
if (event.finished) {
// Fire our callback now
next();
}
// Everytime our even has finished, fire the callback
this.on(eventName + ':finished', next);
return this;
}
// When, alias for on
}, {
key: 'when',
value: function when() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return this.on.apply(this, args);
}
// Block an event from running
// next(err)
}, {
key: 'block',
value: function block(eventNames, next) {
var done, err, eventName, i, len, total;
// Ensure array
if (!typeChecker.isArray(eventNames)) {
if (typeChecker.isString(eventNames)) {
eventNames = eventNames.split(/[,\s]+/g);
} else {
err = new Error('Unknown eventNames type');
return next(err);
}
}
total = eventNames.length;
done = 0;
// Block these events
for (i = 0, len = eventNames.length; i < len; i++) {
eventName = eventNames[i];
this.lock(eventName, function (err) {
// Error?
if (err) {
done = total;
return next(err);
}
// Increment
done++;
if (done === total) {
return next();
}
});
}
return this;
}
// Unblock an event from running
// next(err)
}, {
key: 'unblock',
value: function unblock(eventNames, next) {
var done, err, eventName, i, len, total;
// Ensure array
if (!typeChecker.isArray(eventNames)) {
if (typeChecker.isString(eventNames)) {
eventNames = eventNames.split(/[,\s]+/g);
} else {
err = new Error('Unknown eventNames type');
return next(err);
}
}
total = eventNames.length;
done = 0;
// Block these events
for (i = 0, len = eventNames.length; i < len; i++) {
eventName = eventNames[i];
this.unlock(eventName, function (err) {
// Error?
if (err) {
done = total;
return next(err);
}
// Increment
done++;
if (done === total) {
return next();
}
});
}
return this;
}
}]);
return EventSystem;
}(EventEmitter);
;
// Event store
// initialised in our event function to prevent javascript reference problems
EventSystem.prototype._eventSystemEvents = null;
return EventSystem;
}.call(undefined);
// =====================================
// Export
module.exports = { Event: Event, EventSystem: EventSystem };