Skip to content

Commit

Permalink
feat(reorganize): operators now all exported from top level
Browse files Browse the repository at this point in the history
- Exports all pipeable operators from `rxjs`.

BREAKING CHANGE: Pipeable operators must now be imported from `rxjs`
like so: `import { map, filter, switchMap } from 'rxjs';`

BREAKING CHANGE: Operator versions of static observable creators such as
`merge`, `concat`, `zip`, `onErrorResumeNext`, and `race` have been
removed. Please use the static versions of those operations. e.g.
`a.pipe(concat(b, c))` becomes `concat(a, b, c)`.
  • Loading branch information
benlesh committed Jan 12, 2018
1 parent 2d5c3f8 commit 308b8b3
Show file tree
Hide file tree
Showing 17 changed files with 864 additions and 682 deletions.
98 changes: 98 additions & 0 deletions spec/index-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,102 @@ describe('index', () => {
expect(index.using).to.exist;
expect(index.zip).to.exist;
});

it('should export operators', () => {
expect(index.audit).to.exist;
expect(index.auditTime).to.exist;
expect(index.buffer).to.exist;
expect(index.bufferCount).to.exist;
expect(index.bufferTime).to.exist;
expect(index.bufferToggle).to.exist;
expect(index.bufferWhen).to.exist;
expect(index.catchError).to.exist;
expect(index.combineAll).to.exist;
expect(index.concatAll).to.exist;
expect(index.concatMap).to.exist;
expect(index.concatMapTo).to.exist;
expect(index.count).to.exist;
expect(index.debounce).to.exist;
expect(index.debounceTime).to.exist;
expect(index.defaultIfEmpty).to.exist;
expect(index.delay).to.exist;
expect(index.delayWhen).to.exist;
expect(index.dematerialize).to.exist;
expect(index.distinct).to.exist;
expect(index.distinctUntilChanged).to.exist;
expect(index.distinctUntilKeyChanged).to.exist;
expect(index.elementAt).to.exist;
expect(index.every).to.exist;
expect(index.exhaust).to.exist;
expect(index.exhaustMap).to.exist;
expect(index.expand).to.exist;
expect(index.filter).to.exist;
expect(index.finalize).to.exist;
expect(index.find).to.exist;
expect(index.findIndex).to.exist;
expect(index.first).to.exist;
expect(index.groupBy).to.exist;
expect(index.ignoreElements).to.exist;
expect(index.isEmpty).to.exist;
expect(index.last).to.exist;
expect(index.map).to.exist;
expect(index.mapTo).to.exist;
expect(index.materialize).to.exist;
expect(index.max).to.exist;
expect(index.mergeAll).to.exist;
expect(index.mergeMap).to.exist;
expect(index.mergeMap).to.exist;
expect(index.mergeMapTo).to.exist;
expect(index.mergeScan).to.exist;
expect(index.min).to.exist;
expect(index.multicast).to.exist;
expect(index.observeOn).to.exist;
expect(index.pairwise).to.exist;
expect(index.partition).to.exist;
expect(index.pluck).to.exist;
expect(index.publish).to.exist;
expect(index.publishBehavior).to.exist;
expect(index.publishLast).to.exist;
expect(index.publishReplay).to.exist;
expect(index.reduce).to.exist;
expect(index.repeat).to.exist;
expect(index.repeatWhen).to.exist;
expect(index.retry).to.exist;
expect(index.retryWhen).to.exist;
expect(index.refCount).to.exist;
expect(index.sample).to.exist;
expect(index.sampleTime).to.exist;
expect(index.scan).to.exist;
expect(index.sequenceEqual).to.exist;
expect(index.share).to.exist;
expect(index.shareReplay).to.exist;
expect(index.single).to.exist;
expect(index.skip).to.exist;
expect(index.skipLast).to.exist;
expect(index.skipUntil).to.exist;
expect(index.skipWhile).to.exist;
expect(index.startWith).to.exist;
expect(index.switchAll).to.exist;
expect(index.switchMap).to.exist;
expect(index.switchMapTo).to.exist;
expect(index.take).to.exist;
expect(index.takeLast).to.exist;
expect(index.takeUntil).to.exist;
expect(index.takeWhile).to.exist;
expect(index.tap).to.exist;
expect(index.throttle).to.exist;
expect(index.throttleTime).to.exist;
expect(index.timeInterval).to.exist;
expect(index.timeout).to.exist;
expect(index.timeoutWith).to.exist;
expect(index.timestamp).to.exist;
expect(index.toArray).to.exist;
expect(index.window).to.exist;
expect(index.windowCount).to.exist;
expect(index.windowTime).to.exist;
expect(index.windowToggle).to.exist;
expect(index.windowWhen).to.exist;
expect(index.withLatestFrom).to.exist;
expect(index.zipAll).to.exist;
});
});
104 changes: 104 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,107 @@ export { _throw as throwError } from './internal/observable/throw';
export { timer } from './internal/observable/timer';
export { using } from './internal/observable/using';
export { zip } from './internal/observable/zip';

/* Operator exports */
export { audit } from './operators/audit';
export { auditTime } from './operators/auditTime';
export { buffer } from './operators/buffer';
export { bufferCount } from './operators/bufferCount';
export { bufferTime } from './operators/bufferTime';
export { bufferToggle } from './operators/bufferToggle';
export { bufferWhen } from './operators/bufferWhen';
export { catchError } from './operators/catchError';
export { combineAll } from './operators/combineAll';
export { concatAll } from './operators/concatAll';
export { concatMap } from './operators/concatMap';
export { concatMapTo } from './operators/concatMapTo';
export { count } from './operators/count';
export { debounce } from './operators/debounce';
export { debounceTime } from './operators/debounceTime';
export { defaultIfEmpty } from './operators/defaultIfEmpty';
export { delay } from './operators/delay';
export { delayWhen } from './operators/delayWhen';
export { dematerialize } from './operators/dematerialize';
export { distinct } from './operators/distinct';
export { distinctUntilChanged } from './operators/distinctUntilChanged';
export { distinctUntilKeyChanged } from './operators/distinctUntilKeyChanged';
export { elementAt } from './operators/elementAt';
export { every } from './operators/every';
export { exhaust } from './operators/exhaust';
export { exhaustMap } from './operators/exhaustMap';
export { expand } from './operators/expand';
export { filter } from './operators/filter';
export { finalize } from './operators/finalize';
export { find } from './operators/find';
export { findIndex } from './operators/findIndex';
export { first } from './operators/first';
export { groupBy } from './operators/groupBy';
export { ignoreElements } from './operators/ignoreElements';
export { isEmpty } from './operators/isEmpty';
export { last } from './operators/last';
export { map } from './operators/map';
export { mapTo } from './operators/mapTo';
export { materialize } from './operators/materialize';
export { max } from './operators/max';
export { mergeAll } from './operators/mergeAll';
export { mergeMap } from './operators/mergeMap';
export { mergeMap as flatMap } from './operators/mergeMap';
export { mergeMapTo } from './operators/mergeMapTo';
export { mergeScan } from './operators/mergeScan';
export { min } from './operators/min';
export { multicast } from './operators/multicast';
export { observeOn } from './operators/observeOn';
export { pairwise } from './operators/pairwise';
export { partition } from './operators/partition';
export { pluck } from './operators/pluck';
export { publish } from './operators/publish';
export { publishBehavior } from './operators/publishBehavior';
export { publishLast } from './operators/publishLast';
export { publishReplay } from './operators/publishReplay';
export { reduce } from './operators/reduce';
export { repeat } from './operators/repeat';
export { repeatWhen } from './operators/repeatWhen';
export { retry } from './operators/retry';
export { retryWhen } from './operators/retryWhen';
export { refCount } from './operators/refCount';
export { sample } from './operators/sample';
export { sampleTime } from './operators/sampleTime';
export { scan } from './operators/scan';
export { sequenceEqual } from './operators/sequenceEqual';
export { share } from './operators/share';
export { shareReplay } from './operators/shareReplay';
export { single } from './operators/single';
export { skip } from './operators/skip';
export { skipLast } from './operators/skipLast';
export { skipUntil } from './operators/skipUntil';
export { skipWhile } from './operators/skipWhile';
export { startWith } from './operators/startWith';
/**
* TODO(https://github.com/ReactiveX/rxjs/issues/2900): Add back subscribeOn once it can be
* treeshaken. Currently if this export is added back, it
* forces apps to bring in asap scheduler along with
* Immediate, root, and other supporting code.
*/
// export { subscribeOn } from './operators/subscribeOn';
export { switchAll } from './operators/switchAll';
export { switchMap } from './operators/switchMap';
export { switchMapTo } from './operators/switchMapTo';
export { take } from './operators/take';
export { takeLast } from './operators/takeLast';
export { takeUntil } from './operators/takeUntil';
export { takeWhile } from './operators/takeWhile';
export { tap } from './operators/tap';
export { throttle } from './operators/throttle';
export { throttleTime } from './operators/throttleTime';
export { timeInterval } from './operators/timeInterval';
export { timeout } from './operators/timeout';
export { timeoutWith } from './operators/timeoutWith';
export { timestamp } from './operators/timestamp';
export { toArray } from './operators/toArray';
export { window } from './operators/window';
export { windowCount } from './operators/windowCount';
export { windowTime } from './operators/windowTime';
export { windowToggle } from './operators/windowToggle';
export { windowWhen } from './operators/windowWhen';
export { withLatestFrom } from './operators/withLatestFrom';
export { zipAll } from './operators/zipAll';
99 changes: 93 additions & 6 deletions src/internal/observable/combineLatest.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Observable, ObservableInput } from '../../Observable';
import { IScheduler } from '../../Scheduler';
import { isScheduler } from '../../util/isScheduler';
import { isArray } from '../../util/isArray';
import { ArrayObservable } from './ArrayObservable';
import { CombineLatestOperator } from '../../operators/combineLatest';
import { Observable, ObservableInput } from '../../Observable';
import { IScheduler } from '../../Scheduler';
import { isScheduler } from '../../util/isScheduler';
import { isArray } from '../../util/isArray';
import { ArrayObservable } from './ArrayObservable';
import { Subscriber } from '../../Subscriber';
import { OuterSubscriber } from '../../OuterSubscriber';
import { Operator } from '../../Operator';
import { InnerSubscriber } from '../../InnerSubscriber';
import { subscribeToResult } from '../../util/subscribeToResult';

const NONE = {};

/* tslint:disable:max-line-length */
export function combineLatest<T, R>(v1: ObservableInput<T>, project: (v1: T) => R, scheduler?: IScheduler): Observable<R>;
Expand Down Expand Up @@ -159,3 +165,84 @@ export function combineLatest<T, R>(...observables: Array<any | ObservableInput<

return new ArrayObservable(observables, scheduler).lift(new CombineLatestOperator<T, R>(project));
}

export class CombineLatestOperator<T, R> implements Operator<T, R> {
constructor(private project?: (...values: Array<any>) => R) {
}

call(subscriber: Subscriber<R>, source: any): any {
return source.subscribe(new CombineLatestSubscriber(subscriber, this.project));
}
}

/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
export class CombineLatestSubscriber<T, R> extends OuterSubscriber<T, R> {
private active: number = 0;
private values: any[] = [];
private observables: any[] = [];
private toRespond: number;

constructor(destination: Subscriber<R>, private project?: (...values: Array<any>) => R) {
super(destination);
}

protected _next(observable: any) {
this.values.push(NONE);
this.observables.push(observable);
}

protected _complete() {
const observables = this.observables;
const len = observables.length;
if (len === 0) {
this.destination.complete();
} else {
this.active = len;
this.toRespond = len;
for (let i = 0; i < len; i++) {
const observable = observables[i];
this.add(subscribeToResult(this, observable, observable, i));
}
}
}

notifyComplete(unused: Subscriber<R>): void {
if ((this.active -= 1) === 0) {
this.destination.complete();
}
}

notifyNext(outerValue: T, innerValue: R,
outerIndex: number, innerIndex: number,
innerSub: InnerSubscriber<T, R>): void {
const values = this.values;
const oldVal = values[outerIndex];
const toRespond = !this.toRespond
? 0
: oldVal === NONE ? --this.toRespond : this.toRespond;
values[outerIndex] = innerValue;

if (toRespond === 0) {
if (this.project) {
this._tryProject(values);
} else {
this.destination.next(values.slice());
}
}
}

private _tryProject(values: any[]) {
let result: any;
try {
result = this.project.apply(this, values);
} catch (err) {
this.destination.error(err);
return;
}
this.destination.next(result);
}
}
Loading

0 comments on commit 308b8b3

Please sign in to comment.