]>
git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/vim-mode/node_modules/grim/node_modules/emissary/lib/signal.js
368f63a37f36c46101ce3f388f3f87c77b1f10d9
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
; },
7 isEqual
= require('underscore-plus').isEqual
;
9 Emitter
= require('./emitter');
11 Subscriber
= require('./subscriber');
15 module
.exports
= Signal
= (function(_super
) {
16 __extends(Signal
, _super
);
18 Subscriber
.includeInto(Signal
);
20 Signal
.fromEmitter = function(emitter
, eventName
) {
21 return new Signal(function() {
23 return this.subscribe(emitter
, eventName
, function() {
25 value
= arguments
[0], metadata
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
26 return _this
.emitValue
.apply(_this
, [value
].concat(__slice
.call(metadata
)));
31 function Signal(subscribeCallback
) {
33 this.subscribeCallback
= subscribeCallback
;
35 this.on('value-subscription-will-be-added', function() {
36 return _this
.retain();
38 this.on('value-subscription-removed', function() {
39 return _this
.release();
43 Signal
.prototype.isSignal
= true;
45 Signal
.prototype.retained = function() {
46 return typeof this.subscribeCallback
=== "function" ? this.subscribeCallback() : void 0;
49 Signal
.prototype.released = function() {
50 return this.unsubscribe();
53 Signal
.prototype.retain = function() {
54 if (++this.retainCount
=== 1) {
55 if (typeof this.retained
=== "function") {
62 Signal
.prototype.release = function() {
63 if (--this.retainCount
=== 0) {
64 if (typeof this.released
=== "function") {
71 Signal
.prototype.onValue = function(handler
) {
72 return this.on('value', handler
);
75 Signal
.prototype.emitValue = function(value
, metadata
) {
76 if (metadata
== null) {
79 if (metadata
.source
== null) {
80 metadata
.source
= this;
82 return this.emit('value', value
, metadata
);
85 Signal
.prototype.toBehavior = function(initialValue
) {
88 return this.buildBehavior(initialValue
, function() {
90 return this.subscribe(source
, 'value', function() {
92 value
= arguments
[0], metadata
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
93 return _this
.emitValue
.apply(_this
, [value
].concat(__slice
.call(metadata
)));
98 Signal
.prototype.changes = function() {
102 Signal
.prototype.injectMetadata = function(fn
) {
105 return new this.constructor(function() {
107 return this.subscribe(source
, 'value', function(value
, metadata
) {
108 var k
, newMetadata
, v
;
109 newMetadata
= fn(value
, metadata
);
110 for (k
in newMetadata
) {
114 return _this
.emitValue(value
, metadata
);
119 Signal
.prototype.filter = function(predicate
) {
122 return new this.constructor(function() {
124 return this.subscribe(source
, 'value', function() {
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
)));
134 Signal
.prototype.filterDefined = function() {
135 return this.filter(function(value
) {
136 return value
!= null;
140 Signal
.prototype.map = function(fn
) {
141 var property
, source
;
142 if (typeof fn
=== 'string') {
144 fn = function(value
) {
145 return value
!= null ? value
[property
] : void 0;
149 return new this.constructor(function() {
151 return this.subscribe(source
, 'value', function() {
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
)));
159 Signal
.prototype["switch"] = function(fn
) {
161 source
= this.map(fn
);
162 return new this.constructor(function() {
165 currentSignal
= null;
166 return this.subscribe(source
, 'value', function(newSignal
, outerMetadata
) {
167 if (currentSignal
!= null) {
168 _this
.unsubscribe(currentSignal
);
170 currentSignal
= newSignal
;
171 if (currentSignal
!= null) {
172 return _this
.subscribe(currentSignal
, 'value', function(value
, innerMetadata
) {
173 return _this
.emitValue(value
, innerMetadata
);
176 return _this
.emitValue(void 0, outerMetadata
);
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
);
190 predicate
= predicateOrTargetValue
;
191 doneSkipping
= false;
192 return this.filter(function(value
) {
196 if (predicate(value
)) {
197 return doneSkipping
= true;
204 Signal
.prototype.scan = function(initialValue
, fn
) {
207 return this.buildBehavior(initialValue
, function() {
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
)));
219 Signal
.prototype.diff = function(initialValue
, fn
) {
222 return this.buildBehavior(function() {
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
;
231 return _this
.emitValue
.apply(_this
, [fn(fnOldValue
, newValue
)].concat(__slice
.call(metadata
)));
236 Signal
.prototype.distinctUntilChanged = function() {
239 return new this.constructor(function() {
240 var oldValue
, receivedValue
,
242 receivedValue
= false;
244 return this.subscribe(source
, 'value', function() {
245 var metadata
, newValue
;
246 newValue
= arguments
[0], metadata
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
248 if (isEqual(oldValue
, newValue
)) {
249 return oldValue
= newValue
;
252 return _this
.emitValue
.apply(_this
, [newValue
].concat(__slice
.call(metadata
)));
255 receivedValue
= true;
257 return _this
.emitValue
.apply(_this
, [newValue
].concat(__slice
.call(metadata
)));
263 Signal
.prototype.equals = function(expected
) {
264 return this.map(function(actual
) {
265 return isEqual(actual
, expected
);
266 }).distinctUntilChanged();
269 Signal
.prototype.isDefined = function() {
270 return this.map(function(value
) {
271 return value
!= null;
272 }).distinctUntilChanged();
275 Signal
.prototype.buildBehavior = function() {
277 args
= 1 <= arguments
.length
? __slice
.call(arguments
, 0) : [];
278 if (Behavior
== null) {
279 Behavior
= require('./behavior');
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(){});