Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

feat(build): Upgrade to TypeScript 2.9 and rxjs6 #1122

Merged
merged 1 commit into from
Sep 6, 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
1 change: 1 addition & 0 deletions karma-base.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module.exports = function(config) {
{pattern: 'node_modules/rxjs/**/**/*.js.map', included: false, watched: false},
{pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
{pattern: 'node_modules/es6-promise/**/*.js', included: false, watched: false},
{pattern: 'node_modules/core-js/**/*.js', included: false, watched: false},
{pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false},
{pattern: 'test/assets/**/*.*', watched: true, served: true, included: false},
{pattern: 'build/**/*.js.map', watched: true, served: true, included: false},
Expand Down
8 changes: 3 additions & 5 deletions lib/rxjs/rxjs-fake-async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Scheduler} from 'rxjs/Scheduler';
import {asap} from 'rxjs/scheduler/asap';
import {async} from 'rxjs/scheduler/async';
import {asapScheduler, asyncScheduler, Scheduler} from 'rxjs';

Zone.__load_patch('rxjs.Scheduler.now', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchMethod(Scheduler, 'now', (delegate: Function) => (self: any, args: any[]) => {
return Date.now.apply(self, args);
});
api.patchMethod(async, 'now', (delegate: Function) => (self: any, args: any[]) => {
api.patchMethod(asyncScheduler, 'now', (delegate: Function) => (self: any, args: any[]) => {
return Date.now.apply(self, args);
});
api.patchMethod(asap, 'now', (delegate: Function) => (self: any, args: any[]) => {
api.patchMethod(asapScheduler, 'now', (delegate: Function) => (self: any, args: any[]) => {
return Date.now.apply(self, args);
});
});
278 changes: 52 additions & 226 deletions lib/rxjs/rxjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,20 @@
* found in the LICENSE file at https://angular.io/license
*/

import 'rxjs/add/observable/bindCallback';
import 'rxjs/add/observable/bindNodeCallback';
import 'rxjs/add/observable/defer';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/observable/fromEventPattern';
import 'rxjs/add/operator/multicast';
import {Observable, Subscriber, Subscription} from 'rxjs';

import {Observable} from 'rxjs/Observable';
import {asap} from 'rxjs/scheduler/asap';
import {Subscriber} from 'rxjs/Subscriber';
import {Subscription} from 'rxjs/Subscription';
import {rxSubscriber} from 'rxjs/symbol/rxSubscriber';

(Zone as any).__load_patch('rxjs', (global: any, Zone: ZoneType) => {
(Zone as any).__load_patch('rxjs', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
const symbol: (symbolString: string) => string = (Zone as any).__symbol__;
const nextSource = 'rxjs.Subscriber.next';
const errorSource = 'rxjs.Subscriber.error';
const completeSource = 'rxjs.Subscriber.complete';

const ObjectDefineProperties = Object.defineProperties;

const empty = {
closed: true,
next(value: any): void{},
error(err: any): void {
throw err;
},
complete(): void {}
};

function toSubscriber<T>(
nextOrObserver?: any, error?: (error: any) => void, complete?: () => void): Subscriber<T> {
if (nextOrObserver) {
if (nextOrObserver instanceof Subscriber) {
return (<Subscriber<T>>nextOrObserver);
}

if (nextOrObserver[rxSubscriber]) {
return nextOrObserver[rxSubscriber]();
}
}

if (!nextOrObserver && !error && !complete) {
return new Subscriber(empty);
}

return new Subscriber(nextOrObserver, error, complete);
}

const patchObservable = function() {
const ObservablePrototype: any = Observable.prototype;
const symbolSubscribe = symbol('subscribe');
const _symbolSubscribe = symbol('_subscribe');
const _subscribe = ObservablePrototype[_symbolSubscribe] = ObservablePrototype._subscribe;
const subscribe = ObservablePrototype[symbolSubscribe] = ObservablePrototype.subscribe;

ObjectDefineProperties(Observable.prototype, {
_zone: {value: null, writable: true, configurable: true},
Expand Down Expand Up @@ -89,30 +48,58 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber';
},
set: function(this: Observable<any>, subscribe: any) {
(this as any)._zone = Zone.current;
(this as any)._zoneSubscribe = subscribe;
(this as any)._zoneSubscribe = function() {
if (this._zone && this._zone !== Zone.current) {
const tearDown = this._zone.run(subscribe, this, arguments);
if (tearDown && typeof tearDown === 'function') {
const zone = this._zone;
return function() {
if (zone !== Zone.current) {
return zone.run(tearDown, this, arguments);
}
return tearDown.apply(this, arguments);
};
}
return tearDown;
}
return subscribe.apply(this, arguments);
};
}
},
subscribe: {
writable: true,
configurable: true,
value: function(this: Observable<any>, observerOrNext: any, error: any, complete: any) {
// Only grab a zone if we Zone exists and it is different from the current zone.
const _zone = (this as any)._zone;
if (_zone && _zone !== Zone.current) {
// Current Zone is different from the intended zone.
// Restore the zone before invoking the subscribe callback.
return _zone.run(subscribe, this, [toSubscriber(observerOrNext, error, complete)]);
}
return subscribe.call(this, observerOrNext, error, complete);
subjectFactory: {
get: function() {
return (this as any)._zoneSubjectFactory;
},
set: function(factory: any) {
const zone = this._zone;
this._zoneSubjectFactory = function() {
if (zone && zone !== Zone.current) {
return zone.run(factory, this, arguments);
}
return factory.apply(this, arguments);
};
}
}
});
};

api.patchMethod(Observable.prototype, 'lift', (delegate: any) => (self: any, args: any[]) => {
const observable: any = delegate.apply(self, args);
if (observable.operator) {
observable.operator._zone = Zone.current;
api.patchMethod(
observable.operator, 'call',
(operatorDelegate: any) => (operatorSelf: any, operatorArgs: any[]) => {
if (operatorSelf._zone && operatorSelf._zone !== Zone.current) {
return operatorSelf._zone.run(operatorDelegate, operatorSelf, operatorArgs);
}
return operatorDelegate.apply(operatorSelf, operatorArgs);
});
}
return observable;
});

const patchSubscription = function() {
const unsubscribeSymbol = symbol('unsubscribe');
const unsubscribe = (Subscription.prototype as any)[unsubscribeSymbol] =
Subscription.prototype.unsubscribe;
ObjectDefineProperties(Subscription.prototype, {
_zone: {value: null, writable: true, configurable: true},
_zoneUnsubscribe: {value: null, writable: true, configurable: true},
Expand All @@ -126,22 +113,12 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber';
},
set: function(this: Subscription, unsubscribe: any) {
(this as any)._zone = Zone.current;
(this as any)._zoneUnsubscribe = unsubscribe;
}
},
unsubscribe: {
writable: true,
configurable: true,
value: function(this: Subscription) {
// Only grab a zone if we Zone exists and it is different from the current zone.
const _zone: Zone = (this as any)._zone;
if (_zone && _zone !== Zone.current) {
// Current Zone is different from the intended zone.
// Restore the zone before invoking the subscribe callback.
_zone.run(unsubscribe, this);
} else {
unsubscribe.apply(this);
}
(this as any)._zoneUnsubscribe = function() {
if (this._zone && this._zone !== Zone.current) {
return this._zone.run(unsubscribe, this, arguments);
}
return unsubscribe.apply(this, arguments);
};
}
}
});
Expand Down Expand Up @@ -205,158 +182,7 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber';
};
};

const patchObservableInstance = function(observable: any) {
observable._zone = Zone.current;
};

const patchObservableFactoryCreator = function(obj: any, factoryName: string) {
const symbolFactory: string = symbol(factoryName);
if (obj[symbolFactory]) {
return;
}
const factoryCreator: any = obj[symbolFactory] = obj[factoryName];
if (!factoryCreator) {
return;
}
obj[factoryName] = function() {
const factory: any = factoryCreator.apply(this, arguments);
return function() {
const observable = factory.apply(this, arguments);
patchObservableInstance(observable);
return observable;
};
};
};

const patchObservableFactory = function(obj: any, factoryName: string) {
const symbolFactory: string = symbol(factoryName);
if (obj[symbolFactory]) {
return;
}
const factory: any = obj[symbolFactory] = obj[factoryName];
if (!factory) {
return;
}
obj[factoryName] = function() {
const observable = factory.apply(this, arguments);
patchObservableInstance(observable);
return observable;
};
};

const patchObservableFactoryArgs = function(obj: any, factoryName: string) {
const symbolFactory: string = symbol(factoryName);
if (obj[symbolFactory]) {
return;
}
const factory: any = obj[symbolFactory] = obj[factoryName];
if (!factory) {
return;
}
obj[factoryName] = function() {
const initZone = Zone.current;
const args = Array.prototype.slice.call(arguments);
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (typeof arg === 'function') {
args[i] = function() {
const argArgs = Array.prototype.slice.call(arguments);
const runningZone = Zone.current;
if (initZone && runningZone && initZone !== runningZone) {
return initZone.run(arg, this, argArgs);
} else {
return arg.apply(this, argArgs);
}
};
}
}

const observable = factory.apply(this, args);
patchObservableInstance(observable);
return observable;
};
};

const patchMulticast = function() {
const obj: any = Observable.prototype;
const factoryName: string = 'multicast';
const symbolFactory: string = symbol(factoryName);
if (obj[symbolFactory]) {
return;
}
const factory: any = obj[symbolFactory] = obj[factoryName];
if (!factory) {
return;
}
obj[factoryName] = function() {
const _zone: any = Zone.current;
const args = Array.prototype.slice.call(arguments);
let subjectOrSubjectFactory: any = args.length > 0 ? args[0] : undefined;
if (typeof subjectOrSubjectFactory !== 'function') {
const originalFactory: any = subjectOrSubjectFactory;
subjectOrSubjectFactory = function() {
return originalFactory;
};
}
args[0] = function() {
let subject: any;
if (_zone && _zone !== Zone.current) {
subject = _zone.run(subjectOrSubjectFactory, this, arguments);
} else {
subject = subjectOrSubjectFactory.apply(this, arguments);
}
if (subject && _zone) {
subject._zone = _zone;
}
return subject;
};
const observable = factory.apply(this, args);
patchObservableInstance(observable);
return observable;
};
};

const patchImmediate = function(asap: any) {
if (!asap) {
return;
}

const scheduleSymbol = symbol('scheduleSymbol');
const zoneSymbol = symbol('zone');
if (asap[scheduleSymbol]) {
return;
}

const schedule = asap[scheduleSymbol] = asap.schedule;
asap.schedule = function() {
const args = Array.prototype.slice.call(arguments);
const work = args.length > 0 ? args[0] : undefined;
const delay = args.length > 1 ? args[1] : 0;
const state = (args.length > 2 ? args[2] : undefined) || {};
state[zoneSymbol] = Zone.current;

const patchedWork = function() {
const workArgs = Array.prototype.slice.call(arguments);
const action = workArgs.length > 0 ? workArgs[0] : undefined;
const scheduleZone = action && action[zoneSymbol];
if (scheduleZone && scheduleZone !== Zone.current) {
return scheduleZone.runGuarded(work, this, arguments);
} else {
return work.apply(this, arguments);
}
};
return schedule.call(this, patchedWork, delay, state);
};
};

patchObservable();
patchSubscription();
patchSubscriber();
patchObservableFactoryCreator(Observable, 'bindCallback');
patchObservableFactoryCreator(Observable, 'bindNodeCallback');
patchObservableFactory(Observable, 'defer');
patchObservableFactory(Observable, 'forkJoin');
patchObservableFactoryArgs(Observable, 'fromEventPattern');
patchMulticast();
patchImmediate(asap);
});
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"clang-format": "^1.2.3",
"concurrently": "^2.2.0",
"conventional-changelog": "^1.1.7",
"core-js": "^2.5.7",
"es6-promise": "^3.0.2",
"google-closure-compiler": "^20170409.0.0",
"gulp": "^3.8.11",
Expand Down Expand Up @@ -93,13 +94,13 @@
"phantomjs": "^2.1.7",
"promises-aplus-tests": "^2.1.2",
"pump": "^1.0.1",
"rxjs": "^5.5.3",
"rxjs": "^6.2.1",
"selenium-webdriver": "^3.4.0",
"systemjs": "^0.19.37",
"ts-loader": "^0.6.0",
"tslint": "^4.1.1",
"tslint-eslint-rules": "^3.1.0",
"typescript": "2.5.2",
"typescript": "2.9.2",
"vrsource-tslint-rules": "^4.0.0",
"webdriver-manager": "^12.0.6",
"webdriverio": "^4.8.0",
Expand Down
2 changes: 2 additions & 0 deletions test/browser_entry_point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/

import 'core-js/features/set';
import 'core-js/features/map';
// List all tests here:
import './common_tests';
import './browser/browser.spec';
Expand Down