Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(config): Move config to a module #3401

Merged
merged 1 commit into from Mar 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 1 addition & 4 deletions spec/Observable-spec.ts
Expand Up @@ -74,9 +74,7 @@ describe('Observable', () => {
it('should allow Promise to be globally configured', (done) => {
let wasCalled = false;

__root__.Rx = {};
__root__.Rx.config = {};
__root__.Rx.config.Promise = function MyPromise(callback: any) {
Rx.config.Promise = function MyPromise(callback: any) {
wasCalled = true;
return new Promise<number>(callback);
};
Expand All @@ -85,7 +83,6 @@ describe('Observable', () => {
expect(x).to.equal(42);
}).then(() => {
expect(wasCalled).to.be.true;
delete __root__.Rx;
done();
});
});
Expand Down
11 changes: 3 additions & 8 deletions spec/operators/toPromise-spec.ts
@@ -1,7 +1,6 @@
import { expect } from 'chai';
import * as Rx from '../../src/internal/Rx';

declare const __root__: any;
const Observable = Rx.Observable;

/** @test {toPromise} */
Expand All @@ -24,18 +23,14 @@ describe('Observable.prototype.toPromise', () => {

it('should allow for global config via Rx.config.Promise', (done: MochaDone) => {
let wasCalled = false;
__root__.Rx = {};
__root__.Rx.config = {};
__root__.Rx.config.Promise = function MyPromise(callback) {
Rx.config.Promise = function MyPromise(callback: Function) {
wasCalled = true;
return new Promise(callback);
};
return new Promise(callback as any);
} as any;

Observable.of(42).toPromise().then((x: number) => {
expect(wasCalled).to.be.true;
expect(x).to.equal(42);

delete __root__.Rx;
done();
});
});
Expand Down
57 changes: 28 additions & 29 deletions src/internal/Observable.ts
Expand Up @@ -2,12 +2,12 @@ import { Operator } from './Operator';
import { Subscriber } from './Subscriber';
import { Subscription } from './Subscription';
import { TeardownLogic } from './types';
import { root } from './util/root';
import { toSubscriber } from './util/toSubscriber';
import { iif } from './observable/iif';
import { observable as Symbol_observable } from '../internal/symbol/observable';
import { OperatorFunction, PartialObserver, Subscribable } from '../internal/types';
import { pipeFromArray } from './util/pipe';
import { config } from './config';

/**
* A representation of any set of values over any amount of time. This is the most basic building block
Expand Down Expand Up @@ -209,24 +209,14 @@ export class Observable<T> implements Subscribable<T> {
/**
* @method forEach
* @param {Function} next a handler for each value emitted by the observable
* @param {PromiseConstructor} [PromiseCtor] a constructor function used to instantiate the Promise
* @param {PromiseConstructor} [promiseCtor] a constructor function used to instantiate the Promise
* @return {Promise} a promise that either resolves on observable completion or
* rejects with the handled error
*/
forEach(next: (value: T) => void, PromiseCtor?: typeof Promise): Promise<void> {
if (!PromiseCtor) {
if (root.Rx && root.Rx.config && root.Rx.config.Promise) {
PromiseCtor = root.Rx.config.Promise;
} else if (root.Promise) {
PromiseCtor = root.Promise;
}
}

if (!PromiseCtor) {
throw new Error('no Promise impl found');
}
forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): PromiseLike<void> {
promiseCtor = getPromiseCtor(promiseCtor);

return new PromiseCtor<void>((resolve, reject) => {
return new promiseCtor<void>((resolve, reject) => {
// Must be declared in a separate statement to avoid a RefernceError when
// accessing subscription below in the closure due to Temporal Dead Zone.
let subscription: Subscription;
Expand Down Expand Up @@ -307,22 +297,31 @@ export class Observable<T> implements Subscribable<T> {
toPromise<T>(this: Observable<T>, PromiseCtor: PromiseConstructorLike): Promise<T>;
/* tslint:enable:max-line-length */

toPromise(PromiseCtor?: PromiseConstructorLike) {
if (!PromiseCtor) {
if (root.Rx && root.Rx.config && root.Rx.config.Promise) {
PromiseCtor = root.Rx.config.Promise;
} else if (root.Promise) {
PromiseCtor = root.Promise;
}
}

if (!PromiseCtor) {
throw new Error('no Promise impl found');
}
toPromise(promiseCtor?: PromiseConstructorLike): PromiseLike<T> {
promiseCtor = getPromiseCtor(promiseCtor);

return new PromiseCtor((resolve, reject) => {
return new promiseCtor((resolve, reject) => {
let value: any;
this.subscribe((x: T) => value = x, (err: any) => reject(err), () => resolve(value));
}) as Promise<T>;
});
}
}

/**
* Decides between a passed promise constructor from consuming code,
* A default configured promise constructor, and the native promise
* constructor and returns it. If nothing can be found, it will throw
* an error.
* @param promiseCtor The optional promise constructor to passed by consuming code
*/
function getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {
if (!promiseCtor) {
promiseCtor = config.Promise || Promise;
}

if (!promiseCtor) {
throw new Error('no Promise impl found');
}

return promiseCtor;
}
2 changes: 2 additions & 0 deletions src/internal/Rx.ts
Expand Up @@ -6,6 +6,8 @@ export {Subject, AnonymousSubject} from './Subject';
/* tslint:enable:no-unused-variable */
export {Observable} from './Observable';

export { config } from './config';

// statics
/* tslint:disable:no-use-before-declare */
import '../add/observable/bindCallback';
Expand Down
11 changes: 11 additions & 0 deletions src/internal/config.ts
@@ -0,0 +1,11 @@
/**
* The global configuration object for RxJS, used to configure things
* like what Promise contructor should used to create Promises
*/
export const config = {
/**
* The promise constructor used by default for methods such as
* {@link toPromise} and {@link forEach}
*/
Promise
};