rxjs-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +19 -0
  4. data/README.md +14 -0
  5. data/lib/rxjs/rails/engine.rb +7 -0
  6. data/lib/rxjs/rails/railtie.rb +7 -0
  7. data/lib/rxjs/rails/version.rb +7 -0
  8. data/lib/rxjs/rails.rb +8 -0
  9. data/lib/rxjs.rb +1 -0
  10. data/rxjs-rails.gemspec +22 -0
  11. data/vendor/assets/javascripts/rx.aggregates.js +687 -0
  12. data/vendor/assets/javascripts/rx.aggregates.min.js +1 -0
  13. data/vendor/assets/javascripts/rx.async.compat.js +376 -0
  14. data/vendor/assets/javascripts/rx.async.compat.min.js +1 -0
  15. data/vendor/assets/javascripts/rx.async.js +306 -0
  16. data/vendor/assets/javascripts/rx.async.min.js +1 -0
  17. data/vendor/assets/javascripts/rx.binding.js +561 -0
  18. data/vendor/assets/javascripts/rx.binding.min.js +1 -0
  19. data/vendor/assets/javascripts/rx.coincidence.js +691 -0
  20. data/vendor/assets/javascripts/rx.coincidence.min.js +1 -0
  21. data/vendor/assets/javascripts/rx.compat.js +4351 -0
  22. data/vendor/assets/javascripts/rx.compat.min.js +2 -0
  23. data/vendor/assets/javascripts/rx.experimental.js +453 -0
  24. data/vendor/assets/javascripts/rx.experimental.min.js +1 -0
  25. data/vendor/assets/javascripts/rx.joinpatterns.js +418 -0
  26. data/vendor/assets/javascripts/rx.joinpatterns.min.js +1 -0
  27. data/vendor/assets/javascripts/rx.lite.compat.js +5188 -0
  28. data/vendor/assets/javascripts/rx.lite.compat.min.js +2 -0
  29. data/vendor/assets/javascripts/rx.lite.js +5000 -0
  30. data/vendor/assets/javascripts/rx.lite.min.js +2 -0
  31. data/vendor/assets/javascripts/rx.min.js +2 -0
  32. data/vendor/assets/javascripts/rx.node.js +143 -0
  33. data/vendor/assets/javascripts/rx.testing.js +503 -0
  34. data/vendor/assets/javascripts/rx.testing.min.js +1 -0
  35. data/vendor/assets/javascripts/rx.time.js +1166 -0
  36. data/vendor/assets/javascripts/rx.time.min.js +1 -0
  37. data/vendor/assets/javascripts/rx.virtualtime.js +336 -0
  38. data/vendor/assets/javascripts/rx.virtualtime.min.js +1 -0
  39. metadata +101 -0
@@ -0,0 +1,1166 @@
1
+ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
2
+
3
+ ;(function (factory) {
4
+ var objectTypes = {
5
+ 'boolean': false,
6
+ 'function': true,
7
+ 'object': true,
8
+ 'number': false,
9
+ 'string': false,
10
+ 'undefined': false
11
+ };
12
+
13
+ var root = (objectTypes[typeof window] && window) || this,
14
+ freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
15
+ freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
16
+ moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
17
+ freeGlobal = objectTypes[typeof global] && global;
18
+
19
+ if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
20
+ root = freeGlobal;
21
+ }
22
+
23
+ // Because of build optimizers
24
+ if (typeof define === 'function' && define.amd) {
25
+ define(['rx', 'exports'], function (Rx, exports) {
26
+ root.Rx = factory(root, exports, Rx);
27
+ return root.Rx;
28
+ });
29
+ } else if (typeof module === 'object' && module && module.exports === freeExports) {
30
+ module.exports = factory(root, module.exports, require('./rx'));
31
+ } else {
32
+ root.Rx = factory(root, {}, root.Rx);
33
+ }
34
+ }.call(this, function (root, exp, Rx, undefined) {
35
+
36
+ // Refernces
37
+ var Observable = Rx.Observable,
38
+ observableProto = Observable.prototype,
39
+ AnonymousObservable = Rx.Internals.AnonymousObservable,
40
+ observableDefer = Observable.defer,
41
+ observableEmpty = Observable.empty,
42
+ observableNever = Observable.never,
43
+ observableThrow = Observable.throwException,
44
+ observableFromArray = Observable.fromArray,
45
+ timeoutScheduler = Rx.Scheduler.timeout,
46
+ SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
47
+ SerialDisposable = Rx.SerialDisposable,
48
+ CompositeDisposable = Rx.CompositeDisposable,
49
+ RefCountDisposable = Rx.RefCountDisposable,
50
+ Subject = Rx.Subject,
51
+ BinaryObserver = Rx.Internals.BinaryObserver,
52
+ addRef = Rx.Internals.addRef,
53
+ normalizeTime = Rx.Scheduler.normalize;
54
+
55
+ function observableTimerDate(dueTime, scheduler) {
56
+ return new AnonymousObservable(function (observer) {
57
+ return scheduler.scheduleWithAbsolute(dueTime, function () {
58
+ observer.onNext(0);
59
+ observer.onCompleted();
60
+ });
61
+ });
62
+ }
63
+
64
+ function observableTimerDateAndPeriod(dueTime, period, scheduler) {
65
+ var p = normalizeTime(period);
66
+ return new AnonymousObservable(function (observer) {
67
+ var count = 0, d = dueTime;
68
+ return scheduler.scheduleRecursiveWithAbsolute(d, function (self) {
69
+ var now;
70
+ if (p > 0) {
71
+ now = scheduler.now();
72
+ d = d + p;
73
+ if (d <= now) {
74
+ d = now + p;
75
+ }
76
+ }
77
+ observer.onNext(count++);
78
+ self(d);
79
+ });
80
+ });
81
+ }
82
+
83
+ function observableTimerTimeSpan(dueTime, scheduler) {
84
+ var d = normalizeTime(dueTime);
85
+ return new AnonymousObservable(function (observer) {
86
+ return scheduler.scheduleWithRelative(d, function () {
87
+ observer.onNext(0);
88
+ observer.onCompleted();
89
+ });
90
+ });
91
+ }
92
+
93
+ function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
94
+ if (dueTime === period) {
95
+ return new AnonymousObservable(function (observer) {
96
+ return scheduler.schedulePeriodicWithState(0, period, function (count) {
97
+ observer.onNext(count);
98
+ return count + 1;
99
+ });
100
+ });
101
+ }
102
+ return observableDefer(function () {
103
+ return observableTimerDateAndPeriod(scheduler.now() + dueTime, period, scheduler);
104
+ });
105
+ }
106
+
107
+ /**
108
+ * Returns an observable sequence that produces a value after each period.
109
+ *
110
+ * @example
111
+ * 1 - res = Rx.Observable.interval(1000);
112
+ * 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
113
+ *
114
+ * @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
115
+ * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
116
+ * @returns {Observable} An observable sequence that produces a value after each period.
117
+ */
118
+ var observableinterval = Observable.interval = function (period, scheduler) {
119
+ scheduler || (scheduler = timeoutScheduler);
120
+ return observableTimerTimeSpanAndPeriod(period, period, scheduler);
121
+ };
122
+
123
+ /**
124
+ * Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
125
+ *
126
+ * @example
127
+ * 1 - res = Rx.Observable.timer(new Date());
128
+ * 2 - res = Rx.Observable.timer(new Date(), 1000);
129
+ * 3 - res = Rx.Observable.timer(new Date(), Rx.Scheduler.timeout);
130
+ * 4 - res = Rx.Observable.timer(new Date(), 1000, Rx.Scheduler.timeout);
131
+ *
132
+ * 5 - res = Rx.Observable.timer(5000);
133
+ * 6 - res = Rx.Observable.timer(5000, 1000);
134
+ * 7 - res = Rx.Observable.timer(5000, Rx.Scheduler.timeout);
135
+ * 8 - res = Rx.Observable.timer(5000, 1000, Rx.Scheduler.timeout);
136
+ *
137
+ * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
138
+ * @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
139
+ * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
140
+ * @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
141
+ */
142
+ var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
143
+ var period;
144
+ scheduler || (scheduler = timeoutScheduler);
145
+ if (periodOrScheduler !== undefined && typeof periodOrScheduler === 'number') {
146
+ period = periodOrScheduler;
147
+ } else if (periodOrScheduler !== undefined && typeof periodOrScheduler === 'object') {
148
+ scheduler = periodOrScheduler;
149
+ }
150
+ if (dueTime instanceof Date && period === undefined) {
151
+ return observableTimerDate(dueTime.getTime(), scheduler);
152
+ }
153
+ if (dueTime instanceof Date && period !== undefined) {
154
+ period = periodOrScheduler;
155
+ return observableTimerDateAndPeriod(dueTime.getTime(), period, scheduler);
156
+ }
157
+ if (period === undefined) {
158
+ return observableTimerTimeSpan(dueTime, scheduler);
159
+ }
160
+ return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
161
+ };
162
+
163
+ function observableDelayTimeSpan(dueTime, scheduler) {
164
+ var source = this;
165
+ return new AnonymousObservable(function (observer) {
166
+ var active = false,
167
+ cancelable = new SerialDisposable(),
168
+ exception = null,
169
+ q = [],
170
+ running = false,
171
+ subscription;
172
+ subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
173
+ var d, shouldRun;
174
+ if (notification.value.kind === 'E') {
175
+ q = [];
176
+ q.push(notification);
177
+ exception = notification.value.exception;
178
+ shouldRun = !running;
179
+ } else {
180
+ q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
181
+ shouldRun = !active;
182
+ active = true;
183
+ }
184
+ if (shouldRun) {
185
+ if (exception !== null) {
186
+ observer.onError(exception);
187
+ } else {
188
+ d = new SingleAssignmentDisposable();
189
+ cancelable.setDisposable(d);
190
+ d.setDisposable(scheduler.scheduleRecursiveWithRelative(dueTime, function (self) {
191
+ var e, recurseDueTime, result, shouldRecurse;
192
+ if (exception !== null) {
193
+ return;
194
+ }
195
+ running = true;
196
+ do {
197
+ result = null;
198
+ if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
199
+ result = q.shift().value;
200
+ }
201
+ if (result !== null) {
202
+ result.accept(observer);
203
+ }
204
+ } while (result !== null);
205
+ shouldRecurse = false;
206
+ recurseDueTime = 0;
207
+ if (q.length > 0) {
208
+ shouldRecurse = true;
209
+ recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
210
+ } else {
211
+ active = false;
212
+ }
213
+ e = exception;
214
+ running = false;
215
+ if (e !== null) {
216
+ observer.onError(e);
217
+ } else if (shouldRecurse) {
218
+ self(recurseDueTime);
219
+ }
220
+ }));
221
+ }
222
+ }
223
+ });
224
+ return new CompositeDisposable(subscription, cancelable);
225
+ });
226
+ }
227
+
228
+ function observableDelayDate(dueTime, scheduler) {
229
+ var self = this;
230
+ return observableDefer(function () {
231
+ var timeSpan = dueTime - scheduler.now();
232
+ return observableDelayTimeSpan.call(self, timeSpan, scheduler);
233
+ });
234
+ }
235
+
236
+ /**
237
+ * Time shifts the observable sequence by dueTime. The relative time intervals between the values are preserved.
238
+ *
239
+ * @example
240
+ * 1 - res = Rx.Observable.delay(new Date());
241
+ * 2 - res = Rx.Observable.delay(new Date(), Rx.Scheduler.timeout);
242
+ *
243
+ * 3 - res = Rx.Observable.delay(5000);
244
+ * 4 - res = Rx.Observable.delay(5000, 1000, Rx.Scheduler.timeout);
245
+ * @memberOf Observable#
246
+ * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
247
+ * @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
248
+ * @returns {Observable} Time-shifted sequence.
249
+ */
250
+ observableProto.delay = function (dueTime, scheduler) {
251
+ scheduler || (scheduler = timeoutScheduler);
252
+ return dueTime instanceof Date ?
253
+ observableDelayDate.call(this, dueTime.getTime(), scheduler) :
254
+ observableDelayTimeSpan.call(this, dueTime, scheduler);
255
+ };
256
+
257
+ /**
258
+ * Ignores values from an observable sequence which are followed by another value before dueTime.
259
+ *
260
+ * @example
261
+ * 1 - res = source.throttle(5000); // 5 seconds
262
+ * 2 - res = source.throttle(5000, scheduler);
263
+ *
264
+ * @param {Number} dueTime Duration of the throttle period for each value (specified as an integer denoting milliseconds).
265
+ * @param {Scheduler} [scheduler] Scheduler to run the throttle timers on. If not specified, the timeout scheduler is used.
266
+ * @returns {Observable} The throttled sequence.
267
+ */
268
+ observableProto.throttle = function (dueTime, scheduler) {
269
+ scheduler || (scheduler = timeoutScheduler);
270
+ var source = this;
271
+ return this.throttleWithSelector(function () { return observableTimer(dueTime, scheduler); })
272
+ };
273
+
274
+ /**
275
+ * Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
276
+ *
277
+ * @example
278
+ * 1 - res = xs.windowWithTime(1000, scheduler); // non-overlapping segments of 1 second
279
+ * 2 - res = xs.windowWithTime(1000, 500 , scheduler); // segments of 1 second with time shift 0.5 seconds
280
+ *
281
+ * @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds).
282
+ * @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows.
283
+ * @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
284
+ * @returns {Observable} An observable sequence of windows.
285
+ */
286
+ observableProto.windowWithTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
287
+ var source = this, timeShift;
288
+ if (timeShiftOrScheduler === undefined) {
289
+ timeShift = timeSpan;
290
+ }
291
+ if (scheduler === undefined) {
292
+ scheduler = timeoutScheduler;
293
+ }
294
+ if (typeof timeShiftOrScheduler === 'number') {
295
+ timeShift = timeShiftOrScheduler;
296
+ } else if (typeof timeShiftOrScheduler === 'object') {
297
+ timeShift = timeSpan;
298
+ scheduler = timeShiftOrScheduler;
299
+ }
300
+ return new AnonymousObservable(function (observer) {
301
+ var groupDisposable,
302
+ nextShift = timeShift,
303
+ nextSpan = timeSpan,
304
+ q = [],
305
+ refCountDisposable,
306
+ timerD = new SerialDisposable(),
307
+ totalTime = 0;
308
+ groupDisposable = new CompositeDisposable(timerD),
309
+ refCountDisposable = new RefCountDisposable(groupDisposable);
310
+
311
+ function createTimer () {
312
+ var m = new SingleAssignmentDisposable(),
313
+ isSpan = false,
314
+ isShift = false;
315
+ timerD.setDisposable(m);
316
+ if (nextSpan === nextShift) {
317
+ isSpan = true;
318
+ isShift = true;
319
+ } else if (nextSpan < nextShift) {
320
+ isSpan = true;
321
+ } else {
322
+ isShift = true;
323
+ }
324
+ var newTotalTime = isSpan ? nextSpan : nextShift,
325
+ ts = newTotalTime - totalTime;
326
+ totalTime = newTotalTime;
327
+ if (isSpan) {
328
+ nextSpan += timeShift;
329
+ }
330
+ if (isShift) {
331
+ nextShift += timeShift;
332
+ }
333
+ m.setDisposable(scheduler.scheduleWithRelative(ts, function () {
334
+ var s;
335
+ if (isShift) {
336
+ s = new Subject();
337
+ q.push(s);
338
+ observer.onNext(addRef(s, refCountDisposable));
339
+ }
340
+ if (isSpan) {
341
+ s = q.shift();
342
+ s.onCompleted();
343
+ }
344
+ createTimer();
345
+ }));
346
+ };
347
+ q.push(new Subject());
348
+ observer.onNext(addRef(q[0], refCountDisposable));
349
+ createTimer();
350
+ groupDisposable.add(source.subscribe(function (x) {
351
+ var i, s;
352
+ for (i = 0; i < q.length; i++) {
353
+ s = q[i];
354
+ s.onNext(x);
355
+ }
356
+ }, function (e) {
357
+ var i, s;
358
+ for (i = 0; i < q.length; i++) {
359
+ s = q[i];
360
+ s.onError(e);
361
+ }
362
+ observer.onError(e);
363
+ }, function () {
364
+ var i, s;
365
+ for (i = 0; i < q.length; i++) {
366
+ s = q[i];
367
+ s.onCompleted();
368
+ }
369
+ observer.onCompleted();
370
+ }));
371
+ return refCountDisposable;
372
+ });
373
+ };
374
+
375
+ /**
376
+ * Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
377
+ * @example
378
+ * 1 - res = source.windowWithTimeOrCount(5000, 50); // 5s or 50 items
379
+ * 2 - res = source.windowWithTimeOrCount(5000, 50, scheduler); //5s or 50 items
380
+ *
381
+ * @memberOf Observable#
382
+ * @param {Number} timeSpan Maximum time length of a window.
383
+ * @param {Number} count Maximum element count of a window.
384
+ * @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
385
+ * @returns {Observable} An observable sequence of windows.
386
+ */
387
+ observableProto.windowWithTimeOrCount = function (timeSpan, count, scheduler) {
388
+ var source = this;
389
+ scheduler || (scheduler = timeoutScheduler);
390
+ return new AnonymousObservable(function (observer) {
391
+ var createTimer,
392
+ groupDisposable,
393
+ n = 0,
394
+ refCountDisposable,
395
+ s,
396
+ timerD = new SerialDisposable(),
397
+ windowId = 0;
398
+ groupDisposable = new CompositeDisposable(timerD);
399
+ refCountDisposable = new RefCountDisposable(groupDisposable);
400
+ createTimer = function (id) {
401
+ var m = new SingleAssignmentDisposable();
402
+ timerD.setDisposable(m);
403
+ m.setDisposable(scheduler.scheduleWithRelative(timeSpan, function () {
404
+ var newId;
405
+ if (id !== windowId) {
406
+ return;
407
+ }
408
+ n = 0;
409
+ newId = ++windowId;
410
+ s.onCompleted();
411
+ s = new Subject();
412
+ observer.onNext(addRef(s, refCountDisposable));
413
+ createTimer(newId);
414
+ }));
415
+ };
416
+ s = new Subject();
417
+ observer.onNext(addRef(s, refCountDisposable));
418
+ createTimer(0);
419
+ groupDisposable.add(source.subscribe(function (x) {
420
+ var newId = 0, newWindow = false;
421
+ s.onNext(x);
422
+ n++;
423
+ if (n === count) {
424
+ newWindow = true;
425
+ n = 0;
426
+ newId = ++windowId;
427
+ s.onCompleted();
428
+ s = new Subject();
429
+ observer.onNext(addRef(s, refCountDisposable));
430
+ }
431
+ if (newWindow) {
432
+ createTimer(newId);
433
+ }
434
+ }, function (e) {
435
+ s.onError(e);
436
+ observer.onError(e);
437
+ }, function () {
438
+ s.onCompleted();
439
+ observer.onCompleted();
440
+ }));
441
+ return refCountDisposable;
442
+ });
443
+ };
444
+
445
+ /**
446
+ * Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
447
+ *
448
+ * @example
449
+ * 1 - res = xs.bufferWithTime(1000, scheduler); // non-overlapping segments of 1 second
450
+ * 2 - res = xs.bufferWithTime(1000, 500, scheduler; // segments of 1 second with time shift 0.5 seconds
451
+ *
452
+ * @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds).
453
+ * @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers.
454
+ * @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
455
+ * @returns {Observable} An observable sequence of buffers.
456
+ */
457
+ observableProto.bufferWithTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
458
+ return this.windowWithTime.apply(this, arguments).selectMany(function (x) { return x.toArray(); });
459
+ };
460
+
461
+ /**
462
+ * Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
463
+ *
464
+ * @example
465
+ * 1 - res = source.bufferWithTimeOrCount(5000, 50); // 5s or 50 items in an array
466
+ * 2 - res = source.bufferWithTimeOrCount(5000, 50, scheduler); // 5s or 50 items in an array
467
+ *
468
+ * @param {Number} timeSpan Maximum time length of a buffer.
469
+ * @param {Number} count Maximum element count of a buffer.
470
+ * @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used.
471
+ * @returns {Observable} An observable sequence of buffers.
472
+ */
473
+ observableProto.bufferWithTimeOrCount = function (timeSpan, count, scheduler) {
474
+ return this.windowWithTimeOrCount(timeSpan, count, scheduler).selectMany(function (x) {
475
+ return x.toArray();
476
+ });
477
+ };
478
+
479
+ /**
480
+ * Records the time interval between consecutive values in an observable sequence.
481
+ *
482
+ * @example
483
+ * 1 - res = source.timeInterval();
484
+ * 2 - res = source.timeInterval(Rx.Scheduler.timeout);
485
+ *
486
+ * @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
487
+ * @returns {Observable} An observable sequence with time interval information on values.
488
+ */
489
+ observableProto.timeInterval = function (scheduler) {
490
+ var source = this;
491
+ scheduler || (scheduler = timeoutScheduler);
492
+ return observableDefer(function () {
493
+ var last = scheduler.now();
494
+ return source.select(function (x) {
495
+ var now = scheduler.now(), span = now - last;
496
+ last = now;
497
+ return {
498
+ value: x,
499
+ interval: span
500
+ };
501
+ });
502
+ });
503
+ };
504
+
505
+ /**
506
+ * Records the timestamp for each value in an observable sequence.
507
+ *
508
+ * @example
509
+ * 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
510
+ * 2 - res = source.timestamp(Rx.Scheduler.timeout);
511
+ *
512
+ * @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the timeout scheduler is used.
513
+ * @returns {Observable} An observable sequence with timestamp information on values.
514
+ */
515
+ observableProto.timestamp = function (scheduler) {
516
+ scheduler || (scheduler = timeoutScheduler);
517
+ return this.select(function (x) {
518
+ return {
519
+ value: x,
520
+ timestamp: scheduler.now()
521
+ };
522
+ });
523
+ };
524
+
525
+ function sampleObservable(source, sampler) {
526
+
527
+ return new AnonymousObservable(function (observer) {
528
+ var atEnd, value, hasValue;
529
+
530
+ function sampleSubscribe() {
531
+ if (hasValue) {
532
+ hasValue = false;
533
+ observer.onNext(value);
534
+ }
535
+ if (atEnd) {
536
+ observer.onCompleted();
537
+ }
538
+ }
539
+
540
+ return new CompositeDisposable(
541
+ source.subscribe(function (newValue) {
542
+ hasValue = true;
543
+ value = newValue;
544
+ }, observer.onError.bind(observer), function () {
545
+ atEnd = true;
546
+ }),
547
+ sampler.subscribe(sampleSubscribe, observer.onError.bind(observer), sampleSubscribe)
548
+ );
549
+ });
550
+ }
551
+
552
+ /**
553
+ * Samples the observable sequence at each interval.
554
+ *
555
+ * @example
556
+ * 1 - res = source.sample(sampleObservable); // Sampler tick sequence
557
+ * 2 - res = source.sample(5000); // 5 seconds
558
+ * 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
559
+ *
560
+ * @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
561
+ * @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
562
+ * @returns {Observable} Sampled observable sequence.
563
+ */
564
+ observableProto.sample = function (intervalOrSampler, scheduler) {
565
+ scheduler || (scheduler = timeoutScheduler);
566
+ if (typeof intervalOrSampler === 'number') {
567
+ return sampleObservable(this, observableinterval(intervalOrSampler, scheduler));
568
+ }
569
+ return sampleObservable(this, intervalOrSampler);
570
+ };
571
+
572
+ /**
573
+ * Returns the source observable sequence or the other observable sequence if dueTime elapses.
574
+ *
575
+ * @example
576
+ * 1 - res = source.timeout(new Date()); // As a date
577
+ * 2 - res = source.timeout(5000); // 5 seconds
578
+ * 3 - res = source.timeout(new Date(), Rx.Observable.returnValue(42)); // As a date and timeout observable
579
+ * 4 - res = source.timeout(5000, Rx.Observable.returnValue(42)); // 5 seconds and timeout observable
580
+ * 5 - res = source.timeout(new Date(), Rx.Observable.returnValue(42), Rx.Scheduler.timeout); // As a date and timeout observable
581
+ * 6 - res = source.timeout(5000, Rx.Observable.returnValue(42), Rx.Scheduler.timeout); // 5 seconds and timeout observable
582
+ *
583
+ * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) when a timeout occurs.
584
+ * @param {Observable} [other] Sequence to return in case of a timeout. If not specified, a timeout error throwing sequence will be used.
585
+ * @param {Scheduler} [scheduler] Scheduler to run the timeout timers on. If not specified, the timeout scheduler is used.
586
+ * @returns {Observable} The source sequence switching to the other sequence in case of a timeout.
587
+ */
588
+ observableProto.timeout = function (dueTime, other, scheduler) {
589
+ var schedulerMethod, source = this;
590
+ other || (other = observableThrow(new Error('Timeout')));
591
+ scheduler || (scheduler = timeoutScheduler);
592
+ if (dueTime instanceof Date) {
593
+ schedulerMethod = function (dt, action) {
594
+ scheduler.scheduleWithAbsolute(dt, action);
595
+ };
596
+ } else {
597
+ schedulerMethod = function (dt, action) {
598
+ scheduler.scheduleWithRelative(dt, action);
599
+ };
600
+ }
601
+ return new AnonymousObservable(function (observer) {
602
+ var createTimer,
603
+ id = 0,
604
+ original = new SingleAssignmentDisposable(),
605
+ subscription = new SerialDisposable(),
606
+ switched = false,
607
+ timer = new SerialDisposable();
608
+ subscription.setDisposable(original);
609
+ createTimer = function () {
610
+ var myId = id;
611
+ timer.setDisposable(schedulerMethod(dueTime, function () {
612
+ switched = id === myId;
613
+ var timerWins = switched;
614
+ if (timerWins) {
615
+ subscription.setDisposable(other.subscribe(observer));
616
+ }
617
+ }));
618
+ };
619
+ createTimer();
620
+ original.setDisposable(source.subscribe(function (x) {
621
+ var onNextWins = !switched;
622
+ if (onNextWins) {
623
+ id++;
624
+ observer.onNext(x);
625
+ createTimer();
626
+ }
627
+ }, function (e) {
628
+ var onErrorWins = !switched;
629
+ if (onErrorWins) {
630
+ id++;
631
+ observer.onError(e);
632
+ }
633
+ }, function () {
634
+ var onCompletedWins = !switched;
635
+ if (onCompletedWins) {
636
+ id++;
637
+ observer.onCompleted();
638
+ }
639
+ }));
640
+ return new CompositeDisposable(subscription, timer);
641
+ });
642
+ };
643
+
644
+ /**
645
+ * Generates an observable sequence by iterating a state from an initial state until the condition fails.
646
+ *
647
+ * @example
648
+ * res = source.generateWithAbsoluteTime(0,
649
+ * function (x) { return return true; },
650
+ * function (x) { return x + 1; },
651
+ * function (x) { return x; },
652
+ * function (x) { return new Date(); }
653
+ * });
654
+ *
655
+ * @param {Mixed} initialState Initial state.
656
+ * @param {Function} condition Condition to terminate generation (upon returning false).
657
+ * @param {Function} iterate Iteration step function.
658
+ * @param {Function} resultSelector Selector function for results produced in the sequence.
659
+ * @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning Date values.
660
+ * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
661
+ * @returns {Observable} The generated sequence.
662
+ */
663
+ Observable.generateWithAbsoluteTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
664
+ scheduler || (scheduler = timeoutScheduler);
665
+ return new AnonymousObservable(function (observer) {
666
+ var first = true,
667
+ hasResult = false,
668
+ result,
669
+ state = initialState,
670
+ time;
671
+ return scheduler.scheduleRecursiveWithAbsolute(scheduler.now(), function (self) {
672
+ if (hasResult) {
673
+ observer.onNext(result);
674
+ }
675
+ try {
676
+ if (first) {
677
+ first = false;
678
+ } else {
679
+ state = iterate(state);
680
+ }
681
+ hasResult = condition(state);
682
+ if (hasResult) {
683
+ result = resultSelector(state);
684
+ time = timeSelector(state);
685
+ }
686
+ } catch (e) {
687
+ observer.onError(e);
688
+ return;
689
+ }
690
+ if (hasResult) {
691
+ self(time);
692
+ } else {
693
+ observer.onCompleted();
694
+ }
695
+ });
696
+ });
697
+ };
698
+
699
+ /**
700
+ * Generates an observable sequence by iterating a state from an initial state until the condition fails.
701
+ *
702
+ * @example
703
+ * res = source.generateWithRelativeTime(0,
704
+ * function (x) { return return true; },
705
+ * function (x) { return x + 1; },
706
+ * function (x) { return x; },
707
+ * function (x) { return 500; }
708
+ * );
709
+ *
710
+ * @param {Mixed} initialState Initial state.
711
+ * @param {Function} condition Condition to terminate generation (upon returning false).
712
+ * @param {Function} iterate Iteration step function.
713
+ * @param {Function} resultSelector Selector function for results produced in the sequence.
714
+ * @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
715
+ * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
716
+ * @returns {Observable} The generated sequence.
717
+ */
718
+ Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
719
+ scheduler || (scheduler = timeoutScheduler);
720
+ return new AnonymousObservable(function (observer) {
721
+ var first = true,
722
+ hasResult = false,
723
+ result,
724
+ state = initialState,
725
+ time;
726
+ return scheduler.scheduleRecursiveWithRelative(0, function (self) {
727
+ if (hasResult) {
728
+ observer.onNext(result);
729
+ }
730
+ try {
731
+ if (first) {
732
+ first = false;
733
+ } else {
734
+ state = iterate(state);
735
+ }
736
+ hasResult = condition(state);
737
+ if (hasResult) {
738
+ result = resultSelector(state);
739
+ time = timeSelector(state);
740
+ }
741
+ } catch (e) {
742
+ observer.onError(e);
743
+ return;
744
+ }
745
+ if (hasResult) {
746
+ self(time);
747
+ } else {
748
+ observer.onCompleted();
749
+ }
750
+ });
751
+ });
752
+ };
753
+
754
+ /**
755
+ * Time shifts the observable sequence by delaying the subscription.
756
+ *
757
+ * @example
758
+ * 1 - res = source.delaySubscription(5000); // 5s
759
+ * 2 - res = source.delaySubscription(5000, Rx.Scheduler.timeout); // 5 seconds
760
+ *
761
+ * @param {Number} dueTime Absolute or relative time to perform the subscription at.
762
+ * @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
763
+ * @returns {Observable} Time-shifted sequence.
764
+ */
765
+ observableProto.delaySubscription = function (dueTime, scheduler) {
766
+ scheduler || (scheduler = timeoutScheduler);
767
+ return this.delayWithSelector(observableTimer(dueTime, scheduler), function () { return observableEmpty(); });
768
+ };
769
+
770
+ /**
771
+ * Time shifts the observable sequence based on a subscription delay and a delay selector function for each element.
772
+ *
773
+ * @example
774
+ * 1 - res = source.delayWithSelector(function (x) { return Rx.Scheduler.timer(5000); }); // with selector only
775
+ * 1 - res = source.delayWithSelector(Rx.Observable.timer(2000), function (x) { return Rx.Observable.timer(x); }); // with delay and selector
776
+ *
777
+ * @param {Observable} [subscriptionDelay] Sequence indicating the delay for the subscription to the source.
778
+ * @param {Function} delayDurationSelector Selector function to retrieve a sequence indicating the delay for each given element.
779
+ * @returns {Observable} Time-shifted sequence.
780
+ */
781
+ observableProto.delayWithSelector = function (subscriptionDelay, delayDurationSelector) {
782
+ var source = this, subDelay, selector;
783
+ if (typeof subscriptionDelay === 'function') {
784
+ selector = subscriptionDelay;
785
+ } else {
786
+ subDelay = subscriptionDelay;
787
+ selector = delayDurationSelector;
788
+ }
789
+ return new AnonymousObservable(function (observer) {
790
+ var delays = new CompositeDisposable(), atEnd = false, done = function () {
791
+ if (atEnd && delays.length === 0) {
792
+ observer.onCompleted();
793
+ }
794
+ }, subscription = new SerialDisposable(), start = function () {
795
+ subscription.setDisposable(source.subscribe(function (x) {
796
+ var delay;
797
+ try {
798
+ delay = selector(x);
799
+ } catch (error) {
800
+ observer.onError(error);
801
+ return;
802
+ }
803
+ var d = new SingleAssignmentDisposable();
804
+ delays.add(d);
805
+ d.setDisposable(delay.subscribe(function () {
806
+ observer.onNext(x);
807
+ delays.remove(d);
808
+ done();
809
+ }, observer.onError.bind(observer), function () {
810
+ observer.onNext(x);
811
+ delays.remove(d);
812
+ done();
813
+ }));
814
+ }, observer.onError.bind(observer), function () {
815
+ atEnd = true;
816
+ subscription.dispose();
817
+ done();
818
+ }));
819
+ };
820
+
821
+ if (!subDelay) {
822
+ start();
823
+ } else {
824
+ subscription.setDisposable(subDelay.subscribe(function () {
825
+ start();
826
+ }, observer.onError.bind(observer), function () { start(); }));
827
+ }
828
+
829
+ return new CompositeDisposable(subscription, delays);
830
+ });
831
+ };
832
+
833
+ /**
834
+ * Returns the source observable sequence, switching to the other observable sequence if a timeout is signaled.
835
+ *
836
+ * @example
837
+ * 1 - res = source.timeoutWithSelector(Rx.Observable.timer(500));
838
+ * 2 - res = source.timeoutWithSelector(Rx.Observable.timer(500), function (x) { return Rx.Observable.timer(200); });
839
+ * 3 - res = source.timeoutWithSelector(Rx.Observable.timer(500), function (x) { return Rx.Observable.timer(200); }, Rx.Observable.returnValue(42));
840
+ *
841
+ * @param {Observable} [firstTimeout] Observable sequence that represents the timeout for the first element. If not provided, this defaults to Observable.never().
842
+ * @param {Function} [timeoutDurationSelector] Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.
843
+ * @param {Observable} [other] Sequence to return in case of a timeout. If not provided, this is set to Observable.throwException().
844
+ * @returns {Observable} The source sequence switching to the other sequence in case of a timeout.
845
+ */
846
+ observableProto.timeoutWithSelector = function (firstTimeout, timeoutdurationSelector, other) {
847
+ if (arguments.length === 1) {
848
+ timeoutdurationSelector = firstTimeout;
849
+ var firstTimeout = observableNever();
850
+ }
851
+ other || (other = observableThrow(new Error('Timeout')));
852
+ var source = this;
853
+ return new AnonymousObservable(function (observer) {
854
+ var subscription = new SerialDisposable(), timer = new SerialDisposable(), original = new SingleAssignmentDisposable();
855
+
856
+ subscription.setDisposable(original);
857
+
858
+ var id = 0, switched = false, setTimer = function (timeout) {
859
+ var myId = id, timerWins = function () {
860
+ return id === myId;
861
+ };
862
+ var d = new SingleAssignmentDisposable();
863
+ timer.setDisposable(d);
864
+ d.setDisposable(timeout.subscribe(function () {
865
+ if (timerWins()) {
866
+ subscription.setDisposable(other.subscribe(observer));
867
+ }
868
+ d.dispose();
869
+ }, function (e) {
870
+ if (timerWins()) {
871
+ observer.onError(e);
872
+ }
873
+ }, function () {
874
+ if (timerWins()) {
875
+ subscription.setDisposable(other.subscribe(observer));
876
+ }
877
+ }));
878
+ };
879
+
880
+ setTimer(firstTimeout);
881
+ var observerWins = function () {
882
+ var res = !switched;
883
+ if (res) {
884
+ id++;
885
+ }
886
+ return res;
887
+ };
888
+
889
+ original.setDisposable(source.subscribe(function (x) {
890
+ if (observerWins()) {
891
+ observer.onNext(x);
892
+ var timeout;
893
+ try {
894
+ timeout = timeoutdurationSelector(x);
895
+ } catch (e) {
896
+ observer.onError(e);
897
+ return;
898
+ }
899
+ setTimer(timeout);
900
+ }
901
+ }, function (e) {
902
+ if (observerWins()) {
903
+ observer.onError(e);
904
+ }
905
+ }, function () {
906
+ if (observerWins()) {
907
+ observer.onCompleted();
908
+ }
909
+ }));
910
+ return new CompositeDisposable(subscription, timer);
911
+ });
912
+ };
913
+
914
+ /**
915
+ * Ignores values from an observable sequence which are followed by another value within a computed throttle duration.
916
+ *
917
+ * @example
918
+ * 1 - res = source.delayWithSelector(function (x) { return Rx.Scheduler.timer(x + x); });
919
+ *
920
+ * @param {Function} throttleDurationSelector Selector function to retrieve a sequence indicating the throttle duration for each given element.
921
+ * @returns {Observable} The throttled sequence.
922
+ */
923
+ observableProto.throttleWithSelector = function (throttleDurationSelector) {
924
+ var source = this;
925
+ return new AnonymousObservable(function (observer) {
926
+ var value, hasValue = false, cancelable = new SerialDisposable(), id = 0, subscription = source.subscribe(function (x) {
927
+ var throttle;
928
+ try {
929
+ throttle = throttleDurationSelector(x);
930
+ } catch (e) {
931
+ observer.onError(e);
932
+ return;
933
+ }
934
+ hasValue = true;
935
+ value = x;
936
+ id++;
937
+ var currentid = id, d = new SingleAssignmentDisposable();
938
+ cancelable.setDisposable(d);
939
+ d.setDisposable(throttle.subscribe(function () {
940
+ if (hasValue && id === currentid) {
941
+ observer.onNext(value);
942
+ }
943
+ hasValue = false;
944
+ d.dispose();
945
+ }, observer.onError.bind(observer), function () {
946
+ if (hasValue && id === currentid) {
947
+ observer.onNext(value);
948
+ }
949
+ hasValue = false;
950
+ d.dispose();
951
+ }));
952
+ }, function (e) {
953
+ cancelable.dispose();
954
+ observer.onError(e);
955
+ hasValue = false;
956
+ id++;
957
+ }, function () {
958
+ cancelable.dispose();
959
+ if (hasValue) {
960
+ observer.onNext(value);
961
+ }
962
+ observer.onCompleted();
963
+ hasValue = false;
964
+ id++;
965
+ });
966
+ return new CompositeDisposable(subscription, cancelable);
967
+ });
968
+ };
969
+
970
+ /**
971
+ * Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
972
+ *
973
+ * 1 - res = source.skipLastWithTime(5000);
974
+ * 2 - res = source.skipLastWithTime(5000, scheduler);
975
+ *
976
+ * @description
977
+ * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
978
+ * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
979
+ * result sequence. This causes elements to be delayed with duration.
980
+ * @param {Number} duration Duration for skipping elements from the end of the sequence.
981
+ * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
982
+ * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
983
+ */
984
+ observableProto.skipLastWithTime = function (duration, scheduler) {
985
+ scheduler || (scheduler = timeoutScheduler);
986
+ var source = this;
987
+ return new AnonymousObservable(function (observer) {
988
+ var q = [];
989
+ return source.subscribe(function (x) {
990
+ var now = scheduler.now();
991
+ q.push({ interval: now, value: x });
992
+ while (q.length > 0 && now - q[0].interval >= duration) {
993
+ observer.onNext(q.shift().value);
994
+ }
995
+ }, observer.onError.bind(observer), function () {
996
+ var now = scheduler.now();
997
+ while (q.length > 0 && now - q[0].interval >= duration) {
998
+ observer.onNext(q.shift().value);
999
+ }
1000
+ observer.onCompleted();
1001
+ });
1002
+ });
1003
+ };
1004
+
1005
+ /**
1006
+ * Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
1007
+ *
1008
+ * @example
1009
+ * 1 - res = source.takeLastWithTime(5000, [optional timer scheduler], [optional loop scheduler]);
1010
+ * @description
1011
+ * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
1012
+ * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
1013
+ * result sequence. This causes elements to be delayed with duration.
1014
+ * @param {Number} duration Duration for taking elements from the end of the sequence.
1015
+ * @param {Scheduler} [timerScheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
1016
+ * @param {Scheduler} [loopScheduler] Scheduler to drain the collected elements. If not specified, defaults to Rx.Scheduler.immediate.
1017
+ * @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
1018
+ */
1019
+ observableProto.takeLastWithTime = function (duration, timerScheduler, loopScheduler) {
1020
+ return this.takeLastBufferWithTime(duration, timerScheduler).selectMany(function (xs) { return observableFromArray(xs, loopScheduler); });
1021
+ };
1022
+
1023
+ /**
1024
+ * Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
1025
+ *
1026
+ * @example
1027
+ * 1 - res = source.takeLastBufferWithTime(5000, [optional scheduler]);
1028
+ * @description
1029
+ * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
1030
+ * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
1031
+ * result sequence. This causes elements to be delayed with duration.
1032
+ * @param {Number} duration Duration for taking elements from the end of the sequence.
1033
+ * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
1034
+ * @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
1035
+ */
1036
+ observableProto.takeLastBufferWithTime = function (duration, scheduler) {
1037
+ var source = this;
1038
+ scheduler || (scheduler = timeoutScheduler);
1039
+ return new AnonymousObservable(function (observer) {
1040
+ var q = [];
1041
+
1042
+ return source.subscribe(function (x) {
1043
+ var now = scheduler.now();
1044
+ q.push({ interval: now, value: x });
1045
+ while (q.length > 0 && now - q[0].interval >= duration) {
1046
+ q.shift();
1047
+ }
1048
+ }, observer.onError.bind(observer), function () {
1049
+ var now = scheduler.now(), res = [];
1050
+ while (q.length > 0) {
1051
+ var next = q.shift();
1052
+ if (now - next.interval <= duration) {
1053
+ res.push(next.value);
1054
+ }
1055
+ }
1056
+
1057
+ observer.onNext(res);
1058
+ observer.onCompleted();
1059
+ });
1060
+ });
1061
+ };
1062
+
1063
+ /**
1064
+ * Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
1065
+ *
1066
+ * @example
1067
+ * 1 - res = source.takeWithTime(5000, [optional scheduler]);
1068
+ * @description
1069
+ * This operator accumulates a queue with a length enough to store elements received during the initial duration window.
1070
+ * As more elements are received, elements older than the specified duration are taken from the queue and produced on the
1071
+ * result sequence. This causes elements to be delayed with duration.
1072
+ * @param {Number} duration Duration for taking elements from the start of the sequence.
1073
+ * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
1074
+ * @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
1075
+ */
1076
+ observableProto.takeWithTime = function (duration, scheduler) {
1077
+ var source = this;
1078
+ scheduler || (scheduler = timeoutScheduler);
1079
+ return new AnonymousObservable(function (observer) {
1080
+ var t = scheduler.scheduleWithRelative(duration, function () {
1081
+ observer.onCompleted();
1082
+ });
1083
+
1084
+ return new CompositeDisposable(t, source.subscribe(observer));
1085
+ });
1086
+ };
1087
+
1088
+ /**
1089
+ * Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
1090
+ *
1091
+ * @example
1092
+ * 1 - res = source.skipWithTime(5000, [optional scheduler]);
1093
+ *
1094
+ * @description
1095
+ * Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
1096
+ * This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
1097
+ * may not execute immediately, despite the zero due time.
1098
+ *
1099
+ * Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
1100
+ * @param {Number} duration Duration for skipping elements from the start of the sequence.
1101
+ * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
1102
+ * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
1103
+ */
1104
+ observableProto.skipWithTime = function (duration, scheduler) {
1105
+ var source = this;
1106
+ scheduler || (scheduler = timeoutScheduler);
1107
+ return new AnonymousObservable(function (observer) {
1108
+ var open = false,
1109
+ t = scheduler.scheduleWithRelative(duration, function () { open = true; }),
1110
+ d = source.subscribe(function (x) {
1111
+ if (open) {
1112
+ observer.onNext(x);
1113
+ }
1114
+ }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
1115
+
1116
+ return new CompositeDisposable(t, d);
1117
+ });
1118
+ };
1119
+
1120
+ /**
1121
+ * Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
1122
+ * Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time>.
1123
+ *
1124
+ * @examples
1125
+ * 1 - res = source.skipUntilWithTime(new Date(), [optional scheduler]);
1126
+ * @param startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
1127
+ * @param scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
1128
+ * @returns {Observable} An observable sequence with the elements skipped until the specified start time.
1129
+ */
1130
+ observableProto.skipUntilWithTime = function (startTime, scheduler) {
1131
+ scheduler || (scheduler = timeoutScheduler);
1132
+ var source = this;
1133
+ return new AnonymousObservable(function (observer) {
1134
+ var open = false,
1135
+ t = scheduler.scheduleWithAbsolute(startTime, function () { open = true; }),
1136
+ d = source.subscribe(function (x) {
1137
+ if (open) {
1138
+ observer.onNext(x);
1139
+ }
1140
+ }, observer.onError.bind(observer), observer.onCompleted.bind(observer));
1141
+
1142
+ return new CompositeDisposable(t, d);
1143
+ });
1144
+ };
1145
+
1146
+ /**
1147
+ * Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
1148
+ *
1149
+ * @example
1150
+ * 1 - res = source.takeUntilWithTime(new Date(), [optional scheduler]);
1151
+ * @param {Number} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
1152
+ * @param {Scheduler} scheduler Scheduler to run the timer on.
1153
+ * @returns {Observable} An observable sequence with the elements taken until the specified end time.
1154
+ */
1155
+ observableProto.takeUntilWithTime = function (endTime, scheduler) {
1156
+ scheduler || (scheduler = timeoutScheduler);
1157
+ var source = this;
1158
+ return new AnonymousObservable(function (observer) {
1159
+ return new CompositeDisposable(scheduler.scheduleWithAbsolute(endTime, function () {
1160
+ observer.onCompleted();
1161
+ }), source.subscribe(observer));
1162
+ });
1163
+ };
1164
+
1165
+ return Rx;
1166
+ }));