All Versions
Latest Version
Avg Release Cycle
21 days
Latest Release
3023 days ago

Changelog History

  • v4.1.0 Changes

    March 07, 2016

    ๐Ÿš€ We are happy to announce the release of RxJS version 4.1. With this release came a few new additions as well as a new system for pulling in what you want.

    Some of the changes are the following:

    • ๐Ÿ— Build What You Want with @rxjs/rx
    • โž• Adding repeatWhen
    • Parity with RxJS v5 names
    • Other changes

    ๐Ÿ— Build What You Want with @rxjs/rx

    ๐Ÿ— One of the biggest requests with RxJS was to build only what you wanted. In previous attempts, we looked at a CLI to build what you wanted, but that was suboptimal experience. Instead, we have ported the existing code base to CommonJS format so that it works right out of the box with Node.js, or with your favorite bundler whether it is Browserify, Webpack, Rollup, etc.

    0๏ธโƒฃ By default, this brings in all of RxJS when you require the @rxjs/rx module:

    const Rx = require('@rxjs/rx');const subscription = Rx.Observable.from([1,2,3]) .filter(x =\> x % 2 === 0) .map(x =\> x + 2) .subscribe(x =\> console.log(`The answer is ${x}`));// =\> The answer is 4 

    Now it is possible to bring in as much or as little as you want by only including the operators you want:

    const fromArray = require('@rxjs/rx/observable/fromArray');const filter = require('@rxjs/rx/observable/filter');const map = require('@rxjs/rx/observable/map');const source = fromArray([1,2,3]);const filtered = filter(source, x =\> x % 2 === 0);const mapped = map(filtered, x =\> x + 2);const subscription = mapped.subscribe( x =\> console.log(`The answer is ${x}`) );// =\> The answer is 4 

    Not only can you bring in certain operators, but you can also add each one to the prototype if you want the nice chaining feature as well.

    const Observable = require('@rxjs/rx/observable');// Add class methods Observable.addToObject({ fromArray: require('@rxjs/rx/observable/fromarray') });// Add instance methods Observable.addToPrototype({ filter: require('@rxjs/rx/observable/filter'), map: require('@rxjs/rx/observable/map') });const subscription = Observable.fromArray([1,2,3]) .filter(x =\> x % 2 === 0) .map(x =\> x + 2) .subscribe(x =\> console.log(`The answer is ${x}`));

    ๐Ÿ’… In addition, we also added some distributions that you will find under our src/modular/dist folder which contains all of RxJS built in a UMD style as well as a "lite" version as well. This should give you the building blocks for creating your own builds of RxJS and taking the only the operators you need.

    โž• Adding repeatWhen

    We often try to keep parity with other Rx versions such as RxJava. To that end, we've added repeatWhen which complements the retryWhen we've had for quite some time. Rather than buffering and replaying the sequence from the source Observable, the repeatWhen resubscribes to and mirrors the source Observable, but only conditionally based upon the Observable you return from the call.

    Here is an example where we can repeat a sequence twice with a delay of 200ms in between time.

    const source = Rx.Observable.just(42) .repeatWhen(function(notifications) { return notifications.scan((acc, x) =\> return acc + x, 0) .delay(200) .takeWhile(count =\> count \< 2); });var subscription = source.subscribe( x =\> console.log(`Next ${x}`, err =\> console.log(`Error ${err}`), () =\> console.log('Completed') );// =\> Next: 42// 200 ms pass// =\> Next: 42// 200 ms pass// =\> Completed

    Parity with RxJS v5 names

    Given the differences between RxJS v4 and RxJS v5, we've made the migration path easier by creating aliases for you such as the following:

    // Prototype methodsObservable.prototype.race = Observable.prototype.amb;Observable.prototype.mergeMap = Observable.prototype.flatMap;Observable.prototype.switchMap = Observable.prototype.flatMapLatest;Observable.prototype.exhaustMap = Observable.prototype.flatMapFirst;Observable.prototype.exhaust = Observable.prototype.switchFirst;Observable.prototype.publishReplay = Observable.prototype.replay;// Object methodsObservable.bindCallback = Observable.fromCallback;Observable.bindNodeCallback = Observable.fromNodeCallback;Observable.race = Observable.amb;

    Other Changes

    • ๐Ÿ› Bug fixes such as to ConnectableObservable so that if the underlying Subject has been disposed, we will no longer attempt to resubscribe to it.
    • โฑ The startWith operator no longer uses Scheduler.currentThread and now uses Scheduler.immediate, as that caused issues with the backpressure operators such as pausable and pausableBuffered.
    • ๐Ÿ“š Documentation bug fixes
  • v4.0.8

    February 17, 2016
  • v4.0.7

    November 13, 2015
  • v4.0.6 Changes

    October 14, 2015

    ๐Ÿš€ This is a bug fix release of the Reactive Extensions for JavaScript (RxJS) for version 4.0 to fix a number of issues. The most prominent being the issue with fromPromise(promise) was swallowing errors from Observable instances which is now fixed. Looking forward, we will continue to work on performance as well as the modular design for those who want to pick and choose which pieces from NPM they want to use.

    ๐ŸŽ Performance Work

    ๐ŸŽ Work continued on performance with Rx.Observable.onErrorResumeNext, Rx.Observable.mergeDelayError as well as our join patterns. Expect this to continue throughout the lifecycle of v4.x.

    ๐Ÿ› Bugs Fixed:

    ๐Ÿš€ These were the bugs fixed during this release since 4.0.0:

    • โฑ #969 - fix for timeout without other Observable
    • โœ… #964 - fixed shared state for zip, combineLatest and withLatestFrom in subscribeCore
    • ๐Ÿš€ #963 - Angular broken with latest release
    • #957 - fix issue with fromEvent not firing
    • #955 - rx.d.ts compilation issue fix
    • #949 - add null handling for isIterable check
    • #947 - add initialValue to
    • #941 - fix for timer which was firing immediately
    • ๐Ÿ“š #939 - documentation fix for find
    • 0๏ธโƒฃ #938 - fix defaultIfEmpty with default value.
    • #936 - fix fromPromise behavior not to swallow errors when used with Rx.Observable.spawn
    • #934 - fix BehaviorSubject inheritance from Observer
    • #932 - include zip in TypeScript exports
    • ๐Ÿ”€ #931 - include merge in TypeScript exports
  • v4.0.5

    October 13, 2015
  • v4.0.3

    October 13, 2015
  • v4.0.2

    October 13, 2015
  • v4.0.1

    October 08, 2015
  • v4.0.0 Changes

    September 26, 2015

    ๐Ÿš€ This is another release in terms of cleaning up our technical debt by simplifying a number of our infrastructure, including our schedulers both for regular usage as well as testing. There were will be a few more point releases from this repository before a switch over the more modern RxJS vNext, including modularity, expression trees, and so forth.

    ๐Ÿ‘ Before we go further, it's worth mentioning that since Microsoft Edge supports ES 2016 Async Functions, you can take advantage of them in whole new ways in RxJS, because as we've had support for returning Promises, we support async functions as well.

    With a very quick example, we can do the following:

    const source = Rx.Observable.of(1,2,3) .flatMap(async function (x, i) { var result = await Promise.resolve(x \* i); return result; });source.subscribe((x) =\> console.log(`Next: ${x}`))// =\> Next: 0// =\> Next: 2// =\> Next: 6

    ๐Ÿš€ Included in this release are the following:

    • A More Complete rx.all.js
    • โฑ Scheduler rewrite
    • โœ… Testing rewrite
    • Collapsing of operators
    • ๐ŸŽ Performance upgrades

    ๐Ÿš€ What's coming next in this release?

    • Modularity
    • ๐ŸŽ More Performance Upgrades

    A More Complete rx.all.js

    ๐Ÿš€ In previous releases, rx.all.js and its compat counterpart rx.all.compat.js contained all of the operators in RxJS, but did not include any of the testing infrastructure. This has been changed so that you no longer need to bring in rx.testing in order to write your own tests.

    โฑ Scheduler Rewrite

    โฑ The schedulers have long had a long of technical debt when brought over directly from the .NET world. To simplify this, we will now have the following contract on the Scheduler as written in TypeScript so that it makes sense as an interface. You will notice that the previous versions which did not have state associated with them are no longer supported. This caused too much overhead to support both, so if you have no state to pass, simply pass null for the state.

    interface IDisposable { dispose(): void}interface IScheduler { // Current time now(): number; // Schedule immediately schedule\<TState\>(state: TState, action: (scheduler: IScheduler, state: TState) =\> IDisposable) : IDisposable; // Schedule relative scheduleFuture\<TState\>(state: TState, dueTime: number, action: (scheduler: IScheduler, state: any) =\> IDisposable) : IDisposable; // Schedule absolute scheduleFuture\<TState\>(state: TState, dueTime: Date, action: (scheduler: IScheduler, state: TState) =\> IDisposable) : IDisposable; // Schedule recursive scheduleRecursive\<TState\>(state: TState, action: (state: TState, action: (state: TState) =\> void) =\> void): IDisposable; // Schedule recursive relative scheduleRecursiveFuture\<TState\>(state: TState, dueTime: number, action: (state: TState, action: (state: TState, dueTime: number) =\> void) =\> void): IDisposable; // Schedule recursive absolute scheduleRecursiveFuture\<TState\>(state: TState, dueTime: Date, action: (state: TState, action: (state: TState, dueTime: Date) =\> void) =\> void): IDisposable; // Schedule periodic schedulePeriodic\<TState\>(state: TState, period: number, action: (state: TState) =\> TState): IDisposable; }

    โฑ Now, to schedule something immediately, you must follow the following code snippet. The return value is optional as we will automatically fix it to be a Disposable if you do not provide us with one.

    var d = scheduler.schedule(null, function (scheduler, state) { console.log('scheduled ASAP'); return Rx.Disposable.empty; });

    โฑ Same applies to scheduling in the future:

    // Scheduled 5 seconds in the future with absolute timevar d = scheduler.scheduleFuture(null, new Date( + 5000), function (scheduler, state) { console.log('scheduled using absolute time'); return Rx.Disposable.empty; });// Scheduled 5 seconds in the future with relative timevar d = scheduler.scheduleFuture(null, 5000 function (scheduler, state) { console.log('scheduled using relative time'); return Rx.Disposable.empty; });

    โฑ You will also notice that the recursive scheduling as well as periodic scheduling removed the versions where no state was involved. Also, it is necessary to enforce that with scheduleRecursiveFuture determines the relative or absolute timing by the return value from the recurse call for example. If you don't wish to use state for the recurse call, simply use recurse(null, dueTime).

    // Absolute schedulingscheduler.scheduleRecursiveFuture(1, new Date( + 5000), function (state, recurse) { if (state \< 10) { recurse(state + 1, new Date( + (state \* 1000)); } });// Relative schedulingscheduler.scheduleRecursiveFuture(1, 5000, function (state, recurse) { if (state \< 10) { recurse(state + 1, state \* 1000); } });

    โœ… Testing Rewrite

    ๐Ÿš€ One of the biggest undertakings in this release was to standardize and clean up our unit tests. Over the past releases, there was a bit of technical debt that needed to be paid off. In this release, our virtual time system as well as our test scheduling was rewritten as to put it more in line with the regular schedulers. We rid ourselves of the WithState operators, simply renaming them to their basic operators such as scheduleAsbolute and scheduleRelative.

    โฑ With the TestScheduler, we cleaned it up so that you can easily specify when a particular timing for the creation, subscription and disposal of the Observable sequence. This is a quick example of a test in action using timing where in the scheduler.startScheduler method as the second parameter, you can pass in an object with some timings for creation, subscription disposal. If you omit this, it will default to the normal timings of 100 for created, 200 for subscribed and 1000 for disposed.

    test('first default', function () { var scheduler = new TestScheduler(); var xs = scheduler.createHotObservable( onNext(150, 1), onCompleted(250) ); var res = scheduler.startScheduler( function () { return xs.first({defaultValue: 42}); }, { created: 100, subscribed: 200, disposed: 1000 } ); res.messages.assertEqual( onNext(250, 42), onCompleted(250) ); xs.subscriptions.assertEqual( subscribe(200, 250) ); });

    โœ… All tests should look like this now making them much easier to read going forward.

    Collapsing of Operators

    โฑ Previously, we had a number of operators such as debounceWithSelector and timeoutWithSelector that were simply overloads of their respective debounce and timeout methods. To avoid confusion having more named operators, we have simply condensed those into debounce and timeout` so that they look like the following:

    Debounce with relative due time:
    โฑ Rx.Observable.prototype.debounce(dueTime, [scheduler])

    Debounce with selector:

    โฑ Timeout with relative or absolute due time:
    โฑ Rx.Observable.prototype.timeout(dueTime, [other], [scheduler])

    โฑ Timeout with selector and optional first timeout:
    โฑ Rx.Observable.prototype.timeout([firstTimeout], timeoutDurationSelector, [other])

    ๐ŸŽ Performance Upgrades

    ๐ŸŽ In this version, we addressed more performance as we rewrote many operators to minimize chained scopes in addition to writing operators from the bottom up instead of relying on composition from other operators. This had some significant increases in some areas. In addition, we also did some shortcuts for example if the Rx.Scheduler.immediate was used, we could swap that out for an inline call with returning an empty disposable.

    ๐ŸŽ In RxJS vNext, many of the performance concerns will be addressed and have shown great progress.

    What's Next

    ๐Ÿš€ There will be a number of more releases for 4.x until vNext is ready which will address a number of issues including:

    • Modularity
    • ๐ŸŽ Performance


    ๐ŸŽ Now that the operators and schedulers have largely stabilized for performance, we're going to fix more of the modularity story, allowing you to bring in only what you need. Work had already begun on this part of the project, but now that the majority of the technical debt has been paid, this makes for a much easier transition.

    ๐ŸŽ Performance

    ๐Ÿš€ Although many operators have been rewritten to minimized chained scopes, there are a number of operators that have not. In this release, we intend to get those operators such as timeout to be optimized for performance and making it more optimized for the GC.

  • v3.1.2

    August 31, 2015