]> git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/ex-mode/node_modules/event-kit/node_modules/grim/node_modules/emissary/lib/signal.js
368f63a37f36c46101ce3f388f3f87c77b1f10d9
[rbdr/dotfiles] / atom / packages / ex-mode / node_modules / event-kit / node_modules / grim / node_modules / emissary / lib / signal.js
1 (function() {
2 var Behavior, Emitter, Signal, Subscriber, isEqual,
3 __hasProp = {}.hasOwnProperty,
4 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
5 __slice = [].slice;
6
7 isEqual = require('underscore-plus').isEqual;
8
9 Emitter = require('./emitter');
10
11 Subscriber = require('./subscriber');
12
13 Behavior = null;
14
15 module.exports = Signal = (function(_super) {
16 __extends(Signal, _super);
17
18 Subscriber.includeInto(Signal);
19
20 Signal.fromEmitter = function(emitter, eventName) {
21 return new Signal(function() {
22 var _this = this;
23 return this.subscribe(emitter, eventName, function() {
24 var metadata, value;
25 value = arguments[0], metadata = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
26 return _this.emitValue.apply(_this, [value].concat(__slice.call(metadata)));
27 });
28 });
29 };
30
31 function Signal(subscribeCallback) {
32 var _this = this;
33 this.subscribeCallback = subscribeCallback;
34 this.retainCount = 0;
35 this.on('value-subscription-will-be-added', function() {
36 return _this.retain();
37 });
38 this.on('value-subscription-removed', function() {
39 return _this.release();
40 });
41 }
42
43 Signal.prototype.isSignal = true;
44
45 Signal.prototype.retained = function() {
46 return typeof this.subscribeCallback === "function" ? this.subscribeCallback() : void 0;
47 };
48
49 Signal.prototype.released = function() {
50 return this.unsubscribe();
51 };
52
53 Signal.prototype.retain = function() {
54 if (++this.retainCount === 1) {
55 if (typeof this.retained === "function") {
56 this.retained();
57 }
58 }
59 return this;
60 };
61
62 Signal.prototype.release = function() {
63 if (--this.retainCount === 0) {
64 if (typeof this.released === "function") {
65 this.released();
66 }
67 }
68 return this;
69 };
70
71 Signal.prototype.onValue = function(handler) {
72 return this.on('value', handler);
73 };
74
75 Signal.prototype.emitValue = function(value, metadata) {
76 if (metadata == null) {
77 metadata = {};
78 }
79 if (metadata.source == null) {
80 metadata.source = this;
81 }
82 return this.emit('value', value, metadata);
83 };
84
85 Signal.prototype.toBehavior = function(initialValue) {
86 var source;
87 source = this;
88 return this.buildBehavior(initialValue, function() {
89 var _this = this;
90 return this.subscribe(source, 'value', function() {
91 var metadata, value;
92 value = arguments[0], metadata = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
93 return _this.emitValue.apply(_this, [value].concat(__slice.call(metadata)));
94 });
95 });
96 };
97
98 Signal.prototype.changes = function() {
99 return this;
100 };
101
102 Signal.prototype.injectMetadata = function(fn) {
103 var source;
104 source = this;
105 return new this.constructor(function() {
106 var _this = this;
107 return this.subscribe(source, 'value', function(value, metadata) {
108 var k, newMetadata, v;
109 newMetadata = fn(value, metadata);
110 for (k in newMetadata) {
111 v = newMetadata[k];
112 metadata[k] = v;
113 }
114 return _this.emitValue(value, metadata);
115 });
116 });
117 };
118
119 Signal.prototype.filter = function(predicate) {
120 var source;
121 source = this;
122 return new this.constructor(function() {
123 var _this = this;
124 return this.subscribe(source, 'value', function() {
125 var metadata, value;
126 value = arguments[0], metadata = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
127 if (predicate.call(value, value)) {
128 return _this.emitValue.apply(_this, [value].concat(__slice.call(metadata)));
129 }
130 });
131 });
132 };
133
134 Signal.prototype.filterDefined = function() {
135 return this.filter(function(value) {
136 return value != null;
137 });
138 };
139
140 Signal.prototype.map = function(fn) {
141 var property, source;
142 if (typeof fn === 'string') {
143 property = fn;
144 fn = function(value) {
145 return value != null ? value[property] : void 0;
146 };
147 }
148 source = this;
149 return new this.constructor(function() {
150 var _this = this;
151 return this.subscribe(source, 'value', function() {
152 var metadata, value;
153 value = arguments[0], metadata = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
154 return _this.emitValue.apply(_this, [fn.call(value, value)].concat(__slice.call(metadata)));
155 });
156 });
157 };
158
159 Signal.prototype["switch"] = function(fn) {
160 var source;
161 source = this.map(fn);
162 return new this.constructor(function() {
163 var currentSignal,
164 _this = this;
165 currentSignal = null;
166 return this.subscribe(source, 'value', function(newSignal, outerMetadata) {
167 if (currentSignal != null) {
168 _this.unsubscribe(currentSignal);
169 }
170 currentSignal = newSignal;
171 if (currentSignal != null) {
172 return _this.subscribe(currentSignal, 'value', function(value, innerMetadata) {
173 return _this.emitValue(value, innerMetadata);
174 });
175 } else {
176 return _this.emitValue(void 0, outerMetadata);
177 }
178 });
179 });
180 };
181
182 Signal.prototype.skipUntil = function(predicateOrTargetValue) {
183 var doneSkipping, predicate, targetValue;
184 if (typeof predicateOrTargetValue !== 'function') {
185 targetValue = predicateOrTargetValue;
186 return this.skipUntil(function(value) {
187 return isEqual(value, targetValue);
188 });
189 }
190 predicate = predicateOrTargetValue;
191 doneSkipping = false;
192 return this.filter(function(value) {
193 if (doneSkipping) {
194 return true;
195 }
196 if (predicate(value)) {
197 return doneSkipping = true;
198 } else {
199 return false;
200 }
201 });
202 };
203
204 Signal.prototype.scan = function(initialValue, fn) {
205 var source;
206 source = this;
207 return this.buildBehavior(initialValue, function() {
208 var oldValue,
209 _this = this;
210 oldValue = initialValue;
211 return this.subscribe(source, 'value', function() {
212 var metadata, newValue;
213 newValue = arguments[0], metadata = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
214 return _this.emitValue.apply(_this, [(oldValue = fn(oldValue, newValue))].concat(__slice.call(metadata)));
215 });
216 });
217 };
218
219 Signal.prototype.diff = function(initialValue, fn) {
220 var source;
221 source = this;
222 return this.buildBehavior(function() {
223 var oldValue,
224 _this = this;
225 oldValue = initialValue;
226 return this.subscribe(source, 'value', function() {
227 var fnOldValue, metadata, newValue;
228 newValue = arguments[0], metadata = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
229 fnOldValue = oldValue;
230 oldValue = newValue;
231 return _this.emitValue.apply(_this, [fn(fnOldValue, newValue)].concat(__slice.call(metadata)));
232 });
233 });
234 };
235
236 Signal.prototype.distinctUntilChanged = function() {
237 var source;
238 source = this;
239 return new this.constructor(function() {
240 var oldValue, receivedValue,
241 _this = this;
242 receivedValue = false;
243 oldValue = void 0;
244 return this.subscribe(source, 'value', function() {
245 var metadata, newValue;
246 newValue = arguments[0], metadata = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
247 if (receivedValue) {
248 if (isEqual(oldValue, newValue)) {
249 return oldValue = newValue;
250 } else {
251 oldValue = newValue;
252 return _this.emitValue.apply(_this, [newValue].concat(__slice.call(metadata)));
253 }
254 } else {
255 receivedValue = true;
256 oldValue = newValue;
257 return _this.emitValue.apply(_this, [newValue].concat(__slice.call(metadata)));
258 }
259 });
260 });
261 };
262
263 Signal.prototype.equals = function(expected) {
264 return this.map(function(actual) {
265 return isEqual(actual, expected);
266 }).distinctUntilChanged();
267 };
268
269 Signal.prototype.isDefined = function() {
270 return this.map(function(value) {
271 return value != null;
272 }).distinctUntilChanged();
273 };
274
275 Signal.prototype.buildBehavior = function() {
276 var args;
277 args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
278 if (Behavior == null) {
279 Behavior = require('./behavior');
280 }
281 return (function(func, args, ctor) {
282 ctor.prototype = func.prototype;
283 var child = new ctor, result = func.apply(child, args);
284 return Object(result) === result ? result : child;
285 })(Behavior, args, function(){});
286 };
287
288 return Signal;
289
290 })(Emitter);
291
292 }).call(this);