Skip to content

Commit fa85464

Browse files
Merge remote-tracking branch 'origin/master' into moar-fp
2 parents 7f769c8 + bc1e1e5 commit fa85464

39 files changed

+555
-171
lines changed

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
<a name="5.3.0"></a>
2+
# [5.3.0](https://github.com/ReactiveX/RxJS/compare/5.2.0...v5.3.0) (2017-04-03)
3+
4+
5+
### Bug Fixes
6+
7+
* **catch:** return type is now the union of input types ([#2478](https://github.com/ReactiveX/RxJS/issues/2478)) ([840def0](https://github.com/ReactiveX/RxJS/commit/840def0))
8+
* **forEach:** fix a temporal dead zone issue in forEach. ([#2474](https://github.com/ReactiveX/RxJS/issues/2474)) ([e9e9801](https://github.com/ReactiveX/RxJS/commit/e9e9801))
9+
* **multicast:** Ensure ConnectableObservables returned by multicast are state-isolated. ([aaa9e6b](https://github.com/ReactiveX/RxJS/commit/aaa9e6b))
10+
* **reduce:** proper TypeScript signature overload ordering ([#2382](https://github.com/ReactiveX/RxJS/issues/2382)) ([f6a4951](https://github.com/ReactiveX/RxJS/commit/f6a4951)), closes [#2338](https://github.com/ReactiveX/RxJS/issues/2338)
11+
* **SafeSubscriber:** SafeSubscriber shouldn't mutate incoming Observers. ([a1778e0](https://github.com/ReactiveX/RxJS/commit/a1778e0))
12+
* **timeout:** Cancels scheduled timeout, if no longer needed ([3e9d529](https://github.com/ReactiveX/RxJS/commit/3e9d529)), closes [#2134](https://github.com/ReactiveX/RxJS/issues/2134) [#2244](https://github.com/ReactiveX/RxJS/issues/2244) [#2355](https://github.com/ReactiveX/RxJS/issues/2355) [#2347](https://github.com/ReactiveX/RxJS/issues/2347) [#2353](https://github.com/ReactiveX/RxJS/issues/2353) [#2254](https://github.com/ReactiveX/RxJS/issues/2254) [#2372](https://github.com/ReactiveX/RxJS/issues/2372) [#1301](https://github.com/ReactiveX/RxJS/issues/1301)
13+
* **zipAll:** complete when the source is empty ([712fece](https://github.com/ReactiveX/RxJS/commit/712fece))
14+
15+
16+
### Features
17+
18+
* **delayWhen:** add index to the selector function ([5d6291e](https://github.com/ReactiveX/RxJS/commit/5d6291e))
19+
* **symbol exports:** symbols now also exported without `$$` prefix to work with Babel UMD exporting ([#2435](https://github.com/ReactiveX/RxJS/issues/2435)) ([747bef6](https://github.com/ReactiveX/RxJS/commit/747bef6)), closes [#2415](https://github.com/ReactiveX/RxJS/issues/2415)
20+
21+
22+
### Performance Improvements
23+
24+
* **bufferCount:** optimize bufferCount operator ([#2359](https://github.com/ReactiveX/RxJS/issues/2359)) ([28d0883](https://github.com/ReactiveX/RxJS/commit/28d0883))
25+
26+
27+
### April Fools
28+
29+
* **smooth:** `smooth()` was never really a thing. Sorry, folks. :D
30+
31+
32+
133
<a name="5.2.0"></a>
234
# [5.2.0](https://github.com/ReactiveX/RxJS/compare/5.1.1...v5.2.0) (2017-02-21)
335

doc/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ RxJS is a library for reactive programming using Observables, to make it easier
1515

1616
- - -
1717

18+
### Find the right Operator
19+
1820
<div class="decision-tree-widget"></div>
1921

2022
**Hint: open your DevTools to experiment with RxJS.**

doc/installation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## ES6 via npm
22

33
```none
4-
npm install rxjs-es
4+
npm install rxjs
55
```
66

77
To import the entire core set of functionality:

package.json

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@reactivex/rxjs",
3-
"version": "5.2.0",
3+
"version": "5.3.0",
44
"description": "Reactive Extensions for modern JavaScript",
55
"main": "index.js",
66
"config": {
@@ -75,10 +75,10 @@
7575
"copy_src_cjs": "mkdirp ./dist/cjs/src && shx cp -r ./src/* ./dist/cjs/src",
7676
"copy_src_es6": "mkdirp ./dist/es6/src && shx cp -r ./src/* ./dist/es6/src",
7777
"commit": "git-cz",
78-
"compile_dist_cjs": "tsc ./dist/cjs/src/Rx.ts ./dist/cjs/src/fp.ts ./dist/cjs/src/add/observable/of.ts -m commonjs --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom --sourceMap --outDir ./dist/cjs --target ES5 -d --diagnostics --pretty --noImplicitAny --noImplicitReturns --noImplicitThis --suppressImplicitAnyIndexErrors --moduleResolution node",
79-
"compile_module_es6": "tsc ./dist/es6/src/Rx.ts ./dist/es6/src/fp.ts ./dist/es6/src/add/observable/of.ts -m es2015 --sourceMap --outDir ./dist/es6 --target ES5 -d --diagnostics --pretty --noImplicitAny --noImplicitReturns --noImplicitThis --suppressImplicitAnyIndexErrors --moduleResolution node --noEmitHelpers --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom ",
80-
"compile_dist_es6_for_docs": "tsc ./dist/es6/src/Rx.ts ./dist/es6/src/fp.ts ./dist/es6/src/add/observable/of.ts ./dist/es6/src/MiscJSDoc.ts -m es2015 --sourceMap --outDir ./dist/es6 --target ES6 -d --diagnostics --pretty --noImplicitAny --noImplicitReturns --noImplicitThis --suppressImplicitAnyIndexErrors --moduleResolution node",
81-
"cover": "shx rm -rf dist/cjs && tsc src/Rx.ts src/fp.ts src/add/observable/of.ts -m commonjs --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom --outDir dist/cjs --sourceMap --target ES5 -d && nyc --reporter=lcov --reporter=html --exclude=spec/support/**/* --exclude=spec-js/**/* --exclude=node_modules mocha --opts spec/support/default.opts spec-js",
78+
"compile_dist_cjs": "tsc ./dist/cjs/src/Rx.ts ./dist/cjs/src/fp.ts ./dist/cjs/src/add/observable/of.ts -m commonjs --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom --sourceMap --outDir ./dist/cjs --target ES5 -d --diagnostics --pretty --noImplicitAny --noImplicitReturns --noImplicitThis --suppressImplicitAnyIndexErrors --moduleResolution node",
79+
"compile_module_es6": "tsc ./dist/es6/src/Rx.ts ./dist/cjs/src/fp.ts ./dist/es6/src/add/observable/of.ts -m es2015 --sourceMap --outDir ./dist/es6 --target ES5 -d --diagnostics --pretty --noImplicitAny --noImplicitReturns --noImplicitThis --suppressImplicitAnyIndexErrors --moduleResolution node --noEmitHelpers --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom ",
80+
"compile_dist_es6_for_docs": "tsc ./dist/es6/src/Rx.ts ./dist/cjs/src/fp.ts ./dist/es6/src/add/observable/of.ts ./dist/es6/src/MiscJSDoc.ts -m es2015 --sourceMap --outDir ./dist/es6 --target ES6 -d --diagnostics --pretty --noImplicitAny --noImplicitReturns --noImplicitThis --suppressImplicitAnyIndexErrors --moduleResolution node",
81+
"cover": "shx rm -rf dist/cjs && tsc src/Rx.ts ./dist/cjs/src/fp.ts src/add/observable/of.ts -m commonjs --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom --outDir dist/cjs --sourceMap --target ES5 -d && nyc --reporter=lcov --reporter=html --exclude=spec/support/**/* --exclude=spec-js/**/* --exclude=node_modules mocha --opts spec/support/default.opts spec-js",
8282
"decision_tree_widget": "cd doc/decision-tree-widget && npm run build && cd ../..",
8383
"doctoc": "doctoc CONTRIBUTING.md",
8484
"generate_packages": "node .make-packages.js",
@@ -92,7 +92,7 @@
9292
"prepublish": "shx rm -rf ./typings && typings install && npm run build_all",
9393
"publish_docs": "./publish_docs.sh",
9494
"test_mocha": "mocha --opts spec/support/default.opts spec-js",
95-
"debug_mocha": "node-debug _mocha --opts spec/support/debug.opts spec-js",
95+
"debug_mocha": "node --inspect --debug-brk ./node_modules/.bin/_mocha --opts spec/support/debug.opts spec-js",
9696
"test_browser": "npm-run-all build_spec_browser && opn spec/support/mocha-browser-runner.html",
9797
"test": "npm-run-all clean_spec build_spec test_mocha clean_spec",
9898
"tests2png": "npm run build_spec && mkdirp tmp/docs/img && mkdirp spec-js/support && shx cp spec/support/*.opts spec-js/support/ && mocha --opts spec/support/tests2png.opts spec-js",
@@ -159,24 +159,24 @@
159159
"escape-string-regexp": "^1.0.5 ",
160160
"esdoc": "^0.4.7",
161161
"eslint": "^3.8.0",
162-
"fs-extra": "^0.30.0",
162+
"fs-extra": "^2.1.2",
163163
"glob": "^7.0.3",
164164
"gm": "^1.22.0",
165-
"google-closure-compiler-js": "^20160916.0.0",
165+
"google-closure-compiler-js": "^20170218.0.0",
166166
"gzip-size": "^3.0.0",
167167
"http-server": "^0.9.0",
168-
"husky": "^0.12.0",
168+
"husky": "^0.13.3",
169169
"lint-staged": "^3.2.5",
170170
"lodash": "^4.15.0",
171171
"madge": "^1.4.3",
172-
"markdown-doctest": "^0.8.1",
172+
"markdown-doctest": "^0.9.1",
173173
"minimist": "^1.2.0",
174174
"mkdirp": "^0.5.1",
175175
"mocha": "^3.0.2",
176176
"mocha-in-sauce": "0.0.1",
177-
"npm-run-all": "^3.1.0",
177+
"npm-run-all": "^4.0.2",
178178
"npm-scripts-info": "^0.3.4",
179-
"nyc": "^8.3.0",
179+
"nyc": "^10.2.0",
180180
"opn-cli": "^3.1.0",
181181
"platform": "^1.3.1",
182182
"promise": "^7.1.1",
@@ -185,17 +185,16 @@
185185
"rollup-plugin-inject": "^2.0.0",
186186
"rollup-plugin-node-resolve": "^2.0.0",
187187
"rx": "latest",
188-
"shx": "^0.1.4",
189-
"sinon": "^2.0.0-pre",
190-
"sinon-chai": "^2.8.0",
188+
"shx": "^0.2.2",
189+
"sinon": "^2.1.0",
190+
"sinon-chai": "^2.9.0",
191191
"source-map-support": "^0.4.0",
192192
"tslib": "^1.5.0",
193193
"tslint": "^4.4.2",
194194
"typescript": "~2.0.6",
195195
"typings": "^2.0.0",
196196
"validate-commit-msg": "^2.3.1",
197197
"watch": "^1.0.1",
198-
"watchify": "3.7.0",
199198
"webpack": "^1.13.1",
200199
"xmlhttprequest": "1.8.0"
201200
},
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var RxOld = require('rx');
2+
var RxNew = require('../../../../index');
3+
4+
module.exports = function (suite) {
5+
var oldBufferCountWithCurrentThreadScheduler = RxOld.Observable.range(0, 25, RxOld.Scheduler.currentThread).bufferWithCount(5, 3);
6+
var newBufferCountWithCurrentThreadScheduler = RxNew.Observable.range(0, 25, RxNew.Scheduler.queue).bufferCount(5, 3);
7+
8+
function _next(x) { }
9+
function _error(e) { }
10+
function _complete() { }
11+
return suite
12+
.add('old bufferCount with current thread scheduler', function () {
13+
oldBufferCountWithCurrentThreadScheduler.subscribe(_next, _error, _complete);
14+
})
15+
.add('new bufferCount with current thread scheduler', function () {
16+
newBufferCountWithCurrentThreadScheduler.subscribe(_next, _error, _complete);
17+
});
18+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var RxOld = require('rx');
2+
var RxNew = require('../../../../index');
3+
4+
module.exports = function (suite) {
5+
var oldBufferCountWithImmediateScheduler = RxOld.Observable.range(0, 25, RxOld.Scheduler.immediate).bufferWithCount(5, 3);
6+
var newBufferCountWithImmediateScheduler = RxNew.Observable.range(0, 25).bufferCount(5, 3);
7+
8+
function _next(x) { }
9+
function _error(e) { }
10+
function _complete() { }
11+
return suite
12+
.add('old bufferCount with immediate scheduler', function () {
13+
oldBufferCountWithImmediateScheduler.subscribe(_next, _error, _complete);
14+
})
15+
.add('new bufferCount with immediate scheduler', function () {
16+
newBufferCountWithImmediateScheduler.subscribe(_next, _error, _complete);
17+
});
18+
};

spec/observables/forkJoin-spec.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,35 @@ describe('Observable.forkJoin', () => {
194194
expectObservable(e1).toBe(expected);
195195
});
196196

197+
it('should not complete when only source never completes', () => {
198+
const e1 = Observable.forkJoin(
199+
hot('--------------')
200+
);
201+
const expected = '-';
202+
203+
expectObservable(e1).toBe(expected);
204+
});
205+
206+
it('should not complete when one of the sources never completes', () => {
207+
const e1 = Observable.forkJoin(
208+
hot('--------------'),
209+
hot('-a---b--c--|')
210+
);
211+
const expected = '-';
212+
213+
expectObservable(e1).toBe(expected);
214+
});
215+
216+
it('should complete when one of the sources never completes but other completes without values', () => {
217+
const e1 = Observable.forkJoin(
218+
hot('--------------'),
219+
hot('------|')
220+
);
221+
const expected = '------|';
222+
223+
expectObservable(e1).toBe(expected);
224+
});
225+
197226
it('should complete if source is not provided', () => {
198227
const e1 = Observable.forkJoin();
199228
const expected = '|';
@@ -245,6 +274,15 @@ describe('Observable.forkJoin', () => {
245274
expectObservable(e1).toBe(expected);
246275
});
247276

277+
it('should raise error when any of source raises error with source that never completes', () => {
278+
const e1 = Observable.forkJoin(
279+
hot('------#'),
280+
hot('----------'));
281+
const expected = '------#';
282+
283+
expectObservable(e1).toBe(expected);
284+
});
285+
248286
it('should raise error when any of source raises error with selector with empty observable', () => {
249287
function selector(x, y) {
250288
return x + y;
@@ -297,6 +335,20 @@ describe('Observable.forkJoin', () => {
297335
expectSubscriptions(e2.subscriptions).toBe(e2subs);
298336
});
299337

338+
it('should unsubscribe other Observables, when one of them errors', () => {
339+
const e1 = hot('--a--^--b--c---d-| ');
340+
const e1subs = '^ ! ';
341+
const e2 = hot('---e-^---f--g-#');
342+
const e2subs = '^ ! ';
343+
const expected = '---------# ';
344+
345+
const result = Observable.forkJoin(e1, e2);
346+
347+
expectObservable(result).toBe(expected);
348+
expectSubscriptions(e1.subscriptions).toBe(e1subs);
349+
expectSubscriptions(e2.subscriptions).toBe(e2subs);
350+
});
351+
300352
it('should support promises', () => {
301353
type(() => {
302354
/* tslint:disable:no-unused-variable */

spec/operators/reduce-spec.ts

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,24 +301,85 @@ describe('Observable.prototype.reduce', () => {
301301
});
302302

303303
it('should accept T typed reducers', () => {
304+
type(() => {
305+
let a: Rx.Observable<{ a: number; b: string }>;
306+
const reduced = a.reduce((acc, value) => {
307+
value.a = acc.a;
308+
value.b = acc.b;
309+
return acc;
310+
});
311+
312+
reduced.subscribe(r => {
313+
r.a.toExponential();
314+
r.b.toLowerCase();
315+
});
316+
});
317+
});
318+
319+
it('should accept R typed reducers when R is assignable to T', () => {
304320
type(() => {
305321
let a: Rx.Observable<{ a?: number; b?: string }>;
306-
a.reduce((acc, value) => {
322+
const reduced = a.reduce((acc, value) => {
307323
value.a = acc.a;
308324
value.b = acc.b;
309325
return acc;
310326
}, {});
327+
328+
reduced.subscribe(r => {
329+
r.a.toExponential();
330+
r.b.toLowerCase();
331+
});
332+
});
333+
});
334+
335+
it('should accept R typed reducers when R is not assignable to T', () => {
336+
type(() => {
337+
let a: Rx.Observable<{ a: number; b: string }>;
338+
const seed = {
339+
as: [1],
340+
bs: ['a']
341+
};
342+
const reduced = a.reduce((acc, value) => {
343+
acc.as.push(value.a);
344+
acc.bs.push(value.b);
345+
return acc;
346+
}, seed);
347+
348+
reduced.subscribe(r => {
349+
r.as[0].toExponential();
350+
r.bs[0].toLowerCase();
351+
});
311352
});
312353
});
313354

314-
it('should accept R typed reducers', () => {
355+
it('should accept R typed reducers and reduce to type R', () => {
315356
type(() => {
316357
let a: Rx.Observable<{ a: number; b: string }>;
317-
a.reduce<{ a?: number; b?: string }>((acc, value) => {
358+
const reduced = a.reduce<{ a?: number; b?: string }>((acc, value) => {
318359
value.a = acc.a;
319360
value.b = acc.b;
320361
return acc;
321362
}, {});
363+
364+
reduced.subscribe(r => {
365+
r.a.toExponential();
366+
r.b.toLowerCase();
367+
});
368+
});
369+
});
370+
371+
it('should accept array of R typed reducers and reduce to array of R', () => {
372+
type(() => {
373+
let a: Rx.Observable<number>;
374+
const reduced = a.reduce((acc, cur) => {
375+
console.log(acc);
376+
acc.push(cur.toString());
377+
return acc;
378+
}, [] as string[]);
379+
380+
reduced.subscribe(rs => {
381+
rs[0].toLowerCase();
382+
});
322383
});
323384
});
324-
});
385+
});

spec/operators/timeout-spec.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import * as Rx from '../../dist/cjs/Rx';
21
import { expect } from 'chai';
2+
import * as Rx from '../../dist/cjs/Rx';
33
import marbleTestingSignature = require('../helpers/marble-testing'); // tslint:disable-line:no-require-imports
44

55
declare const { asDiagram };
6+
declare const rxTestScheduler: Rx.TestScheduler;
67
declare const hot: typeof marbleTestingSignature.hot;
78
declare const cold: typeof marbleTestingSignature.cold;
89
declare const expectObservable: typeof marbleTestingSignature.expectObservable;
910
declare const expectSubscriptions: typeof marbleTestingSignature.expectSubscriptions;
1011

11-
declare const rxTestScheduler: Rx.TestScheduler;
1212
const Observable = Rx.Observable;
1313

1414
/** @test {timeout} */
@@ -121,4 +121,28 @@ describe('Observable.prototype.timeout', () => {
121121
expectObservable(result).toBe(expected, values, defaultTimeoutError);
122122
expectSubscriptions(e1.subscriptions).toBe(e1subs);
123123
});
124+
125+
it('should unsubscribe from the scheduled timeout action when timeout is unsubscribed early', () => {
126+
const e1 = hot('--a--b--c---d--e--|');
127+
const e1subs = '^ ! ';
128+
const expected = '--a--b--c-- ';
129+
const unsub = ' ! ';
130+
131+
const result = e1
132+
.lift({
133+
call: (timeoutSubscriber, source) => {
134+
const { action } = <any> timeoutSubscriber; // get a ref to the action here
135+
timeoutSubscriber.add(() => { // because it'll be null by the
136+
if (!action.closed) { // time we get into this function.
137+
throw new Error('TimeoutSubscriber scheduled action wasn\'t canceled');
138+
}
139+
});
140+
return source.subscribe(timeoutSubscriber);
141+
}
142+
})
143+
.timeout(50, rxTestScheduler);
144+
145+
expectObservable(result, unsub).toBe(expected);
146+
expectSubscriptions(e1.subscriptions).toBe(e1subs);
147+
});
124148
});

0 commit comments

Comments
 (0)