refactor(async): refactor EventEmitter
Refactor EventEmitter and Async Facade to match ES7 Observable semantics, properly use RxJS typedefs, make EventEmitter inherit from RxJS Subject. Closes #4149. BREAKING CHANGE: - consumers of EventEmitter no longer need to call .toRx() - EventEmitter is now generic and requires a type - e.g. `EventEmitter<string>` - EventEmitter and Observable now use the `.subscribe(generatorOrNext, error, complete)` method instead of `.observer(generator)` - ObservableWrapper uses `callNext/callError/callComplete` instead of `callNext/callThrow/callReturn`
This commit is contained in:
parent
72e65d6797
commit
ca3986f31d
|
@ -1,5 +1,5 @@
|
|||
// Public API for Facade
|
||||
export {ConcreteType, Type} from './facade/lang';
|
||||
export {Observable, EventEmitter} from './facade/async';
|
||||
export {Observable, EventEmitter, Subject} from './facade/async';
|
||||
export {Predicate} from './facade/collection';
|
||||
export {WrappedException} from './facade/exceptions';
|
||||
|
|
|
@ -50,16 +50,16 @@ class ObservableWrapper {
|
|||
emitter.add(value);
|
||||
}
|
||||
|
||||
static void callThrow(EventEmitter emitter, error) {
|
||||
static void callError(EventEmitter emitter, error) {
|
||||
emitter.addError(error);
|
||||
}
|
||||
|
||||
static void callReturn(EventEmitter emitter) {
|
||||
static void callComplete(EventEmitter emitter) {
|
||||
emitter.close();
|
||||
}
|
||||
}
|
||||
|
||||
class EventEmitter extends Stream {
|
||||
class EventEmitter<T> extends Stream<T> {
|
||||
StreamController<dynamic> _controller;
|
||||
|
||||
/// Creates an instance of [EventEmitter], which depending on [isAsync],
|
||||
|
@ -86,3 +86,30 @@ class EventEmitter extends Stream {
|
|||
_controller.close();
|
||||
}
|
||||
}
|
||||
|
||||
//todo(robwormald): maybe fix in ts2dart?
|
||||
class Subject<T> extends Stream<T> {
|
||||
StreamController<dynamic> _controller;
|
||||
|
||||
Subject([bool isAsync = true]) {
|
||||
_controller = new StreamController.broadcast(sync: !isAsync);
|
||||
}
|
||||
|
||||
StreamSubscription listen(void onData(dynamic line),
|
||||
{void onError(Error error), void onDone(), bool cancelOnError}) {
|
||||
return _controller.stream.listen(onData,
|
||||
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
|
||||
}
|
||||
|
||||
void add(value) {
|
||||
_controller.add(value);
|
||||
}
|
||||
|
||||
void addError(error) {
|
||||
_controller.addError(error);
|
||||
}
|
||||
|
||||
void close() {
|
||||
_controller.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ import {global, isPresent} from 'angular2/src/core/facade/lang';
|
|||
// without depending on rxjs.
|
||||
import {PromiseWrapper, Promise, PromiseCompleter} from 'angular2/src/core/facade/promise';
|
||||
export {PromiseWrapper, Promise, PromiseCompleter} from 'angular2/src/core/facade/promise';
|
||||
// TODO(jeffbcross): use ES6 import once typings are available
|
||||
var Subject = require('@reactivex/rxjs/dist/cjs/Subject');
|
||||
import {Subject, Subscription, Observable as RxObservable} from '@reactivex/rxjs/dist/cjs/Rx';
|
||||
import Operator from '@reactivex/rxjs/dist/cjs/Operator';
|
||||
|
||||
export namespace NodeJS {
|
||||
export interface Timer {}
|
||||
|
@ -24,31 +24,26 @@ export class TimerWrapper {
|
|||
|
||||
export class ObservableWrapper {
|
||||
// TODO(vsavkin): when we use rxnext, try inferring the generic type from the first arg
|
||||
static subscribe<T>(emitter: Observable, onNext: (value: T) => void,
|
||||
onThrow: (exception: any) => void = null,
|
||||
onReturn: () => void = null): Object {
|
||||
return emitter.observer({next: onNext, throw: onThrow, return: onReturn});
|
||||
static subscribe<T>(emitter: any, onNext: (value: T) => void,
|
||||
onError: (exception: any) => void = null,
|
||||
onComplete: () => void = null): Object {
|
||||
return emitter.subscribe({next: onNext, error: onError, complete: onComplete});
|
||||
}
|
||||
|
||||
static isObservable(obs: any): boolean { return obs instanceof Observable; }
|
||||
static isObservable(obs: any): boolean { return obs instanceof EventEmitter; }
|
||||
|
||||
/**
|
||||
* Returns whether `obs` has any subscribers listening to events.
|
||||
*/
|
||||
static hasSubscribers(obs: EventEmitter): boolean { return obs._subject.observers.length > 0; }
|
||||
static hasSubscribers(obs: EventEmitter<any>): boolean { return obs.observers.length > 0; }
|
||||
|
||||
static dispose(subscription: any) { subscription.unsubscribe(); }
|
||||
|
||||
static callNext(emitter: EventEmitter, value: any) { emitter.next(value); }
|
||||
static callNext(emitter: EventEmitter<any>, value: any) { emitter.next(value); }
|
||||
|
||||
static callThrow(emitter: EventEmitter, error: any) { emitter.throw(error); }
|
||||
static callError(emitter: EventEmitter<any>, error: any) { emitter.error(error); }
|
||||
|
||||
static callReturn(emitter: EventEmitter) { emitter.return (null); }
|
||||
}
|
||||
|
||||
// TODO: vsavkin change to interface
|
||||
export class Observable {
|
||||
observer(generator: any): Object { return null; }
|
||||
static callComplete(emitter: EventEmitter<any>) { emitter.complete(); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,9 +85,7 @@ export class Observable {
|
|||
*
|
||||
* Once a reference implementation of the spec is available, switch to it.
|
||||
*/
|
||||
export class EventEmitter extends Observable {
|
||||
/** @internal */
|
||||
_subject = new Subject();
|
||||
export class EventEmitter<T> extends Subject<T> {
|
||||
/** @internal */
|
||||
_isAsync: boolean;
|
||||
|
||||
|
@ -105,19 +98,32 @@ export class EventEmitter extends Observable {
|
|||
this._isAsync = isAsync;
|
||||
}
|
||||
|
||||
observer(generator: any): any {
|
||||
var schedulerFn = this._isAsync ? (value) => { setTimeout(() => generator.next(value)); } :
|
||||
(value) => { generator.next(value); };
|
||||
return this._subject.subscribe(schedulerFn,
|
||||
(error) => generator.throw ? generator.throw(error) : null,
|
||||
() => generator.return ? generator.return () : null);
|
||||
subscribe(generatorOrNext?: any, error?: any, complete?: any): any {
|
||||
if (generatorOrNext && typeof generatorOrNext === 'object') {
|
||||
let schedulerFn = this._isAsync ?
|
||||
(value) => { setTimeout(() => generatorOrNext.next(value)); } :
|
||||
(value) => { generatorOrNext.next(value); };
|
||||
return super.subscribe(schedulerFn,
|
||||
(err) => generatorOrNext.error ? generatorOrNext.error(err) : null,
|
||||
() => generatorOrNext.complete ? generatorOrNext.complete() : null);
|
||||
} else {
|
||||
let schedulerFn = this._isAsync ? (value) => { setTimeout(() => generatorOrNext(value)); } :
|
||||
(value) => { generatorOrNext(value); };
|
||||
|
||||
return super.subscribe(schedulerFn, (err) => error ? error(err) : null,
|
||||
() => complete ? complete() : null);
|
||||
}
|
||||
}
|
||||
|
||||
toRx(): any { return this._subject; }
|
||||
|
||||
next(value: any) { this._subject.next(value); }
|
||||
|
||||
throw(error: any) { this._subject.error(error); }
|
||||
|
||||
return (value?: any) { this._subject.complete(); }
|
||||
}
|
||||
|
||||
// todo(robwormald): ts2dart should handle this properly
|
||||
export class Observable<T> extends RxObservable<T> {
|
||||
lift<T, R>(operator: Operator<T, R>): Observable<T> {
|
||||
const observable = new Observable();
|
||||
observable.source = this;
|
||||
observable.operator = operator;
|
||||
return observable;
|
||||
}
|
||||
}
|
||||
|
||||
export {Subject}
|
||||
|
|
|
@ -51,7 +51,7 @@ export abstract class AbstractControl {
|
|||
_value: any;
|
||||
|
||||
/** @internal */
|
||||
_valueChanges: EventEmitter;
|
||||
_valueChanges: EventEmitter<any>;
|
||||
|
||||
private _status: string;
|
||||
private _errors: {[key: string]: any};
|
||||
|
@ -86,7 +86,8 @@ export abstract class AbstractControl {
|
|||
|
||||
get untouched(): boolean { return !this._touched; }
|
||||
|
||||
get valueChanges(): Observable { return this._valueChanges; }
|
||||
get valueChanges(): Observable<any> { return this._valueChanges; }
|
||||
|
||||
get pending(): boolean { return this._status == PENDING; }
|
||||
|
||||
markAsTouched(): void { this._touched = true; }
|
||||
|
|
|
@ -31,7 +31,7 @@ export class QueryList<T> {
|
|||
private _results: Array<T> = [];
|
||||
private _emitter = new EventEmitter();
|
||||
|
||||
get changes(): Observable { return this._emitter; }
|
||||
get changes(): Observable<any> { return this._emitter; }
|
||||
get length(): number { return this._results.length; }
|
||||
get first(): T { return ListWrapper.first(this._results); }
|
||||
get last(): T { return ListWrapper.last(this._results); }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {isBlank, isPresent, isPromise, CONST} from 'angular2/src/core/facade/lang';
|
||||
import {Promise, ObservableWrapper, Observable} from 'angular2/src/core/facade/async';
|
||||
import {Promise, ObservableWrapper, Observable, EventEmitter} from 'angular2/src/core/facade/async';
|
||||
import {Pipe} from 'angular2/src/core/metadata';
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {
|
||||
|
@ -69,7 +69,7 @@ export class AsyncPipe implements PipeTransform, PipeOnDestroy {
|
|||
/** @internal */
|
||||
_subscription: Object = null;
|
||||
/** @internal */
|
||||
_obj: Observable | Promise<any> = null;
|
||||
_obj: Observable<any>| Promise<any>| EventEmitter<any> = null;
|
||||
private _strategy: any = null;
|
||||
/** @internal */
|
||||
public _ref: ChangeDetectorRef;
|
||||
|
@ -81,7 +81,7 @@ export class AsyncPipe implements PipeTransform, PipeOnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
transform(obj: Observable | Promise<any>, args?: any[]): any {
|
||||
transform(obj: Observable<any>| Promise<any>| EventEmitter<any>, args?: any[]): any {
|
||||
if (isBlank(this._obj)) {
|
||||
if (isPresent(obj)) {
|
||||
this._subscribe(obj);
|
||||
|
@ -103,7 +103,7 @@ export class AsyncPipe implements PipeTransform, PipeOnDestroy {
|
|||
}
|
||||
|
||||
/** @internal */
|
||||
_subscribe(obj: Observable | Promise<any>): void {
|
||||
_subscribe(obj: Observable<any>| Promise<any>| EventEmitter<any>): void {
|
||||
this._obj = obj;
|
||||
this._strategy = this._selectStrategy(obj);
|
||||
this._subscription =
|
||||
|
@ -111,7 +111,7 @@ export class AsyncPipe implements PipeTransform, PipeOnDestroy {
|
|||
}
|
||||
|
||||
/** @internal */
|
||||
_selectStrategy(obj: Observable | Promise<any>): any {
|
||||
_selectStrategy(obj: Observable<any>| Promise<any>| EventEmitter<any>): any {
|
||||
if (isPromise(obj)) {
|
||||
return _promiseStrategy;
|
||||
} else if (ObservableWrapper.isObservable(obj)) {
|
||||
|
|
|
@ -113,13 +113,13 @@ export class NgZone {
|
|||
_onErrorHandler: ErrorHandlingFn;
|
||||
|
||||
/** @internal */
|
||||
_onTurnStartEvents: EventEmitter;
|
||||
_onTurnStartEvents: EventEmitter<any>;
|
||||
/** @internal */
|
||||
_onTurnDoneEvents: EventEmitter;
|
||||
_onTurnDoneEvents: EventEmitter<any>;
|
||||
/** @internal */
|
||||
_onEventDoneEvents: EventEmitter;
|
||||
_onEventDoneEvents: EventEmitter<any>;
|
||||
/** @internal */
|
||||
_onErrorEvents: EventEmitter;
|
||||
_onErrorEvents: EventEmitter<any>;
|
||||
|
||||
// Number of microtasks pending from _innerZone (& descendants)
|
||||
/** @internal */
|
||||
|
|
|
@ -9,7 +9,7 @@ export class SpyLocation implements Location {
|
|||
/** @internal */
|
||||
_query: string = '';
|
||||
/** @internal */
|
||||
_subject: EventEmitter = new EventEmitter();
|
||||
_subject: EventEmitter<any> = new EventEmitter();
|
||||
/** @internal */
|
||||
_baseHref: string = '';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ export class MockLocationStrategy extends LocationStrategy {
|
|||
internalTitle: string = '';
|
||||
urlChanges: string[] = [];
|
||||
/** @internal */
|
||||
_subject: EventEmitter = new EventEmitter();
|
||||
_subject: EventEmitter<any> = new EventEmitter();
|
||||
constructor() { super(); }
|
||||
|
||||
simulatePopState(url: string): void {
|
||||
|
|
|
@ -79,7 +79,7 @@ export const APP_BASE_HREF: OpaqueToken = CONST_EXPR(new OpaqueToken('appBaseHre
|
|||
@Injectable()
|
||||
export class Location {
|
||||
/** @internal */
|
||||
_subject: EventEmitter = new EventEmitter();
|
||||
_subject: EventEmitter<any> = new EventEmitter();
|
||||
/** @internal */
|
||||
_baseHref: string;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ export class Router {
|
|||
private _auxRouters = new Map<string, Router>();
|
||||
private _childRouter: Router;
|
||||
|
||||
private _subject: EventEmitter = new EventEmitter();
|
||||
private _subject: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
|
||||
constructor(public registry: RouteRegistry, public parent: Router, public hostComponent: any) {}
|
||||
|
|
|
@ -44,7 +44,7 @@ export abstract class ClientMessageBroker {
|
|||
|
||||
export class ClientMessageBroker_ extends ClientMessageBroker {
|
||||
private _pending: Map<string, PromiseCompleter<any>> = new Map<string, PromiseCompleter<any>>();
|
||||
private _sink: EventEmitter;
|
||||
private _sink: EventEmitter<any>;
|
||||
/** @internal */
|
||||
public _serializer: Serializer;
|
||||
|
||||
|
|
|
@ -30,14 +30,14 @@ export abstract class MessageBus implements MessageBusSource, MessageBusSink {
|
|||
* Returns an {@link EventEmitter} that emits every time a message
|
||||
* is received on the given channel.
|
||||
*/
|
||||
abstract from(channel: string): EventEmitter;
|
||||
abstract from(channel: string): EventEmitter<any>;
|
||||
|
||||
|
||||
/**
|
||||
* Returns an {@link EventEmitter} for the given channel
|
||||
* To publish methods to that channel just call next (or add in dart) on the returned emitter
|
||||
*/
|
||||
abstract to(channel: string): EventEmitter;
|
||||
abstract to(channel: string): EventEmitter<any>;
|
||||
}
|
||||
|
||||
export interface MessageBusSource {
|
||||
|
@ -60,7 +60,7 @@ export interface MessageBusSource {
|
|||
* Returns an {@link EventEmitter} that emits every time a message
|
||||
* is received on the given channel.
|
||||
*/
|
||||
from(channel: string): EventEmitter;
|
||||
from(channel: string): EventEmitter<any>;
|
||||
}
|
||||
|
||||
export interface MessageBusSink {
|
||||
|
@ -83,5 +83,5 @@ export interface MessageBusSink {
|
|||
* Returns an {@link EventEmitter} for the given channel
|
||||
* To publish methods to that channel just call next (or add in dart) on the returned emitter
|
||||
*/
|
||||
to(channel: string): EventEmitter;
|
||||
to(channel: string): EventEmitter<any>;
|
||||
}
|
||||
|
|
|
@ -27,9 +27,9 @@ export class PostMessageBus implements MessageBus {
|
|||
this.sink.initChannel(channel, runInZone);
|
||||
}
|
||||
|
||||
from(channel: string): EventEmitter { return this.source.from(channel); }
|
||||
from(channel: string): EventEmitter<any> { return this.source.from(channel); }
|
||||
|
||||
to(channel: string): EventEmitter { return this.sink.to(channel); }
|
||||
to(channel: string): EventEmitter<any> { return this.sink.to(channel); }
|
||||
}
|
||||
|
||||
export class PostMessageBusSink implements MessageBusSink {
|
||||
|
@ -52,19 +52,17 @@ export class PostMessageBusSink implements MessageBusSink {
|
|||
var emitter = new EventEmitter();
|
||||
var channelInfo = new _Channel(emitter, runInZone);
|
||||
this._channels[channel] = channelInfo;
|
||||
emitter.observer({
|
||||
next: (data: Object) => {
|
||||
var message = {channel: channel, message: data};
|
||||
if (runInZone) {
|
||||
this._messageBuffer.push(message);
|
||||
} else {
|
||||
this._sendMessages([message]);
|
||||
}
|
||||
emitter.subscribe((data: Object) => {
|
||||
var message = {channel: channel, message: data};
|
||||
if (runInZone) {
|
||||
this._messageBuffer.push(message);
|
||||
} else {
|
||||
this._sendMessages([message]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
to(channel: string): EventEmitter {
|
||||
to(channel: string): EventEmitter<any> {
|
||||
if (StringMapWrapper.contains(this._channels, channel)) {
|
||||
return this._channels[channel].emitter;
|
||||
} else {
|
||||
|
@ -107,7 +105,7 @@ export class PostMessageBusSource implements MessageBusSource {
|
|||
this._channels[channel] = channelInfo;
|
||||
}
|
||||
|
||||
from(channel: string): EventEmitter {
|
||||
from(channel: string): EventEmitter<any> {
|
||||
if (StringMapWrapper.contains(this._channels, channel)) {
|
||||
return this._channels[channel].emitter;
|
||||
} else {
|
||||
|
@ -140,7 +138,7 @@ export class PostMessageBusSource implements MessageBusSource {
|
|||
* keeps track of if it should run in the zone.
|
||||
*/
|
||||
class _Channel {
|
||||
constructor(public emitter: EventEmitter, public runInZone: boolean) {}
|
||||
constructor(public emitter: EventEmitter<any>, public runInZone: boolean) {}
|
||||
}
|
||||
|
||||
// TODO(jteplitz602) Replace this with the definition in lib.webworker.d.ts(#3492)
|
||||
|
|
|
@ -45,7 +45,7 @@ export abstract class ServiceMessageBroker {
|
|||
* If that method returns a promise, the UIMessageBroker returns the result to the worker.
|
||||
*/
|
||||
export class ServiceMessageBroker_ extends ServiceMessageBroker {
|
||||
private _sink: EventEmitter;
|
||||
private _sink: EventEmitter<any>;
|
||||
private _methods: Map<string, Function> = new Map<string, Function>();
|
||||
|
||||
constructor(messageBus: MessageBus, private _serializer: Serializer, public channel) {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {StringMapWrapper} from 'angular2/src/core/facade/collection';
|
|||
import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
|
||||
|
||||
export class EventDispatcher implements RenderEventDispatcher {
|
||||
constructor(private _viewRef: RenderViewRef, private _sink: EventEmitter,
|
||||
constructor(private _viewRef: RenderViewRef, private _sink: EventEmitter<any>,
|
||||
private _serializer: Serializer) {}
|
||||
|
||||
dispatchRenderEvent(elementIndex: number, eventName: string, locals: Map<string, any>): boolean {
|
||||
|
|
|
@ -89,7 +89,7 @@ class ParentComp {
|
|||
@Directive({selector: 'custom-emitter', outputs: ['myevent']})
|
||||
@Injectable()
|
||||
class CustomEmitter {
|
||||
myevent: EventEmitter;
|
||||
myevent: EventEmitter<any>;
|
||||
|
||||
constructor() { this.myevent = new EventEmitter(); }
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import {ObservableWrapper, EventEmitter, PromiseWrapper} from 'angular2/src/core
|
|||
|
||||
export function main() {
|
||||
describe('EventEmitter', () => {
|
||||
var emitter: EventEmitter;
|
||||
var emitter: EventEmitter<any>;
|
||||
|
||||
beforeEach(() => { emitter = new EventEmitter(); });
|
||||
|
||||
|
@ -34,18 +34,18 @@ export function main() {
|
|||
expect(error).toEqual("Boom");
|
||||
async.done();
|
||||
});
|
||||
ObservableWrapper.callThrow(emitter, "Boom");
|
||||
ObservableWrapper.callError(emitter, "Boom");
|
||||
}));
|
||||
|
||||
it("should work when no throw callback is provided", inject([AsyncTestCompleter], (async) => {
|
||||
ObservableWrapper.subscribe(emitter, (_) => {}, (_) => { async.done(); });
|
||||
ObservableWrapper.callThrow(emitter, "Boom");
|
||||
ObservableWrapper.callError(emitter, "Boom");
|
||||
}));
|
||||
|
||||
it("should call the return callback", inject([AsyncTestCompleter], (async) => {
|
||||
ObservableWrapper.subscribe(emitter, (_) => {}, (_) => {}, () => { async.done(); });
|
||||
|
||||
ObservableWrapper.callReturn(emitter);
|
||||
ObservableWrapper.callComplete(emitter);
|
||||
}));
|
||||
|
||||
it("should subscribe to the wrapper asynchronously", () => {
|
||||
|
|
|
@ -907,7 +907,7 @@ class WrappedValue implements ControlValueAccessor {
|
|||
|
||||
@Component({selector: "my-input", template: ''})
|
||||
class MyInput implements ControlValueAccessor {
|
||||
@Output('change') onChange: EventEmitter = new EventEmitter();
|
||||
@Output('change') onChange: EventEmitter<any> = new EventEmitter();
|
||||
value: string;
|
||||
|
||||
constructor(cd: NgControl) { cd.valueAccessor = this; }
|
||||
|
|
|
@ -133,7 +133,7 @@ export function main() {
|
|||
if (!IS_DART) {
|
||||
it("should update set errors and status before emitting an event",
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
c.valueChanges.toRx().subscribe(value => {
|
||||
c.valueChanges.subscribe(value => {
|
||||
expect(c.valid).toEqual(false);
|
||||
expect(c.errors).toEqual({"required": true});
|
||||
async.done();
|
||||
|
|
|
@ -1976,7 +1976,7 @@ class DoublePipe implements PipeTransform {
|
|||
@Injectable()
|
||||
class DirectiveEmitingEvent {
|
||||
msg: string;
|
||||
event: EventEmitter;
|
||||
event: EventEmitter<any>;
|
||||
|
||||
constructor() {
|
||||
this.msg = '';
|
||||
|
@ -2002,7 +2002,7 @@ class DirectiveUpdatingHostProperties {
|
|||
@Directive({selector: '[update-host-actions]', host: {'@setAttr': 'setAttribute'}})
|
||||
@Injectable()
|
||||
class DirectiveUpdatingHostActions {
|
||||
setAttr: EventEmitter;
|
||||
setAttr: EventEmitter<any>;
|
||||
|
||||
constructor() { this.setAttr = new EventEmitter(); }
|
||||
|
||||
|
|
|
@ -486,7 +486,12 @@ var NG_API = [
|
|||
'ErrorHandlingFn:dart',
|
||||
'Output',
|
||||
'Output.bindingPropertyName',
|
||||
|
||||
'EventEmitter',
|
||||
|
||||
/*
|
||||
Dart Stream/EventEmitter
|
||||
*/
|
||||
'EventEmitter.add():dart',
|
||||
'EventEmitter.addError():dart',
|
||||
'EventEmitter.any():dart',
|
||||
|
@ -513,24 +518,215 @@ var NG_API = [
|
|||
'EventEmitter.length:dart',
|
||||
'EventEmitter.listen():dart',
|
||||
'EventEmitter.map():dart',
|
||||
'EventEmitter.next():js',
|
||||
'EventEmitter.observer():js',
|
||||
'EventEmitter.pipe():dart',
|
||||
'EventEmitter.reduce():dart',
|
||||
'EventEmitter.return():js',
|
||||
'EventEmitter.single:dart',
|
||||
'EventEmitter.singleWhere():dart',
|
||||
'EventEmitter.skip():dart',
|
||||
'EventEmitter.skipWhile():dart',
|
||||
'EventEmitter.take():dart',
|
||||
'EventEmitter.takeWhile():dart',
|
||||
'EventEmitter.throw():js',
|
||||
'EventEmitter.timeout():dart',
|
||||
'EventEmitter.toList():dart',
|
||||
'EventEmitter.toRx():js',
|
||||
'EventEmitter.toSet():dart',
|
||||
'EventEmitter.transform():dart',
|
||||
'EventEmitter.where():dart',
|
||||
|
||||
/*
|
||||
RxJS API - may need to maintain as RxJS evolves
|
||||
*/
|
||||
'EventEmitter.mapTo():js',
|
||||
'EventEmitter.next():js',
|
||||
'EventEmitter.materialize():js',
|
||||
'EventEmitter.merge():js',
|
||||
'EventEmitter.mergeAll():js',
|
||||
'EventEmitter.mergeMap():js',
|
||||
'EventEmitter.mergeMapTo():js',
|
||||
'EventEmitter.multicast():js',
|
||||
'EventEmitter.observeOn():js',
|
||||
'EventEmitter.remove():js',
|
||||
'EventEmitter.repeat():js',
|
||||
'EventEmitter.retry():js',
|
||||
'EventEmitter.retryWhen():js',
|
||||
'EventEmitter.throttle():js',
|
||||
'EventEmitter.toPromise():js',
|
||||
'EventEmitter.window():js',
|
||||
'EventEmitter.windowCount():js',
|
||||
'EventEmitter.windowTime():js',
|
||||
'EventEmitter.windowToggle():js',
|
||||
'EventEmitter.windowWhen():js',
|
||||
'EventEmitter.withLatestFrom():js',
|
||||
'EventEmitter.zip():js',
|
||||
'EventEmitter.zipAll():js',
|
||||
|
||||
'Observable:js',
|
||||
'Observable#combineLatest():js',
|
||||
'Observable#concat():js',
|
||||
'Observable#create():js',
|
||||
'Observable#defer():js',
|
||||
'Observable#empty():js',
|
||||
'Observable#forkJoin():js',
|
||||
'Observable#from():js',
|
||||
'Observable#fromArray():js',
|
||||
'Observable#fromEvent():js',
|
||||
'Observable#fromEventPattern():js',
|
||||
'Observable#fromPromise():js',
|
||||
'Observable#interval():js',
|
||||
'Observable#merge():js',
|
||||
'Observable#never():js',
|
||||
'Observable#of():js',
|
||||
'Observable#range():js',
|
||||
'Observable#throw():js',
|
||||
'Observable#timer():js',
|
||||
'Observable#zip():js',
|
||||
'Observable.buffer():js',
|
||||
'Observable.bufferCount():js',
|
||||
'Observable.bufferTime():js',
|
||||
'Observable.bufferToggle():js',
|
||||
'Observable.bufferWhen():js',
|
||||
'Observable.catch():js',
|
||||
'Observable.combineAll():js',
|
||||
'Observable.combineLatest():js',
|
||||
'Observable.concat():js',
|
||||
'Observable.concatAll():js',
|
||||
'Observable.concatMap():js',
|
||||
'Observable.concatMapTo():js',
|
||||
'Observable.count():js',
|
||||
'Observable.debounce():js',
|
||||
'Observable.debounceTime():js',
|
||||
'Observable.defaultIfEmpty():js',
|
||||
'Observable.delay():js',
|
||||
'Observable.dematerialize():js',
|
||||
'Observable.distinctUntilChanged():js',
|
||||
'Observable.do():js',
|
||||
'Observable.every():js',
|
||||
'Observable.expand():js',
|
||||
'Observable.filter():js',
|
||||
'Observable.finally():js',
|
||||
'Observable.first():js',
|
||||
'Observable.flatMap():js',
|
||||
'Observable.flatMapTo():js',
|
||||
'Observable.forEach():js',
|
||||
'Observable.groupBy():js',
|
||||
'Observable.ignoreElements():js',
|
||||
'Observable.last():js',
|
||||
'Observable.lift():js',
|
||||
'Observable.map():js',
|
||||
'Observable.mapTo():js',
|
||||
'Observable.materialize():js',
|
||||
'Observable.merge():js',
|
||||
'Observable.mergeAll():js',
|
||||
'Observable.mergeMap():js',
|
||||
'Observable.mergeMapTo():js',
|
||||
'Observable.multicast():js',
|
||||
'Observable.observeOn():js',
|
||||
|
||||
'Subject',
|
||||
'Subject#combineLatest():js',
|
||||
'Subject#concat():js',
|
||||
'Subject#create():js',
|
||||
'Subject#defer():js',
|
||||
'Subject#empty():js',
|
||||
'Subject#forkJoin():js',
|
||||
'Subject#from():js',
|
||||
'Subject#fromArray():js',
|
||||
'Subject#fromEvent():js',
|
||||
'Subject#fromEventPattern():js',
|
||||
'Subject#fromPromise():js',
|
||||
'Subject#interval():js',
|
||||
'Subject#merge():js',
|
||||
'Subject#never():js',
|
||||
'Subject#of():js',
|
||||
'Subject#range():js',
|
||||
'Subject#throw():js',
|
||||
'Subject#timer():js',
|
||||
'Subject#zip():js',
|
||||
'Subject.add():js',
|
||||
'Subject.buffer():js',
|
||||
'Subject.bufferCount():js',
|
||||
'Subject.bufferTime():js',
|
||||
'Subject.bufferToggle():js',
|
||||
'Subject.bufferWhen():js',
|
||||
'Subject.catch():js',
|
||||
'Subject.combineAll():js',
|
||||
'Subject.combineLatest():js',
|
||||
'Subject.complete():js',
|
||||
'Subject.concat():js',
|
||||
'Subject.concatAll():js',
|
||||
'Subject.concatMap():js',
|
||||
'Subject.concatMapTo():js',
|
||||
'Subject.count():js',
|
||||
'Subject.debounce():js',
|
||||
'Subject.debounceTime():js',
|
||||
'Subject.defaultIfEmpty():js',
|
||||
'Subject.delay():js',
|
||||
'Subject.dematerialize():js',
|
||||
'Subject.distinctUntilChanged():js',
|
||||
'Subject.do():js',
|
||||
'Subject.error():js',
|
||||
'Subject.every():js',
|
||||
'Subject.expand():js',
|
||||
'Subject.filter():js',
|
||||
'Subject.finally():js',
|
||||
'Subject.first():js',
|
||||
'Subject.flatMap():js',
|
||||
'Subject.flatMapTo():js',
|
||||
'Subject.forEach():js',
|
||||
'Subject.groupBy():js',
|
||||
'Subject.ignoreElements():js',
|
||||
'Subject.last():js',
|
||||
'Subject.lift():js',
|
||||
'Subject.map():js',
|
||||
'Subject.mapTo():js',
|
||||
'Subject.materialize():js',
|
||||
'Subject.merge():js',
|
||||
'Subject.mergeAll():js',
|
||||
'Subject.mergeMap():js',
|
||||
'Subject.mergeMapTo():js',
|
||||
'Subject.multicast():js',
|
||||
'Subject.next():js',
|
||||
'Subject.observeOn():js',
|
||||
'Subject.partition():js',
|
||||
'Subject.publish():js',
|
||||
'Subject.publishBehavior():js',
|
||||
'Subject.publishReplay():js',
|
||||
'Subject.reduce():js',
|
||||
'Subject.remove():js',
|
||||
'Subject.repeat():js',
|
||||
'Subject.retry():js',
|
||||
'Subject.retryWhen():js',
|
||||
'Subject.sample():js',
|
||||
'Subject.sampleTime():js',
|
||||
'Subject.scan():js',
|
||||
'Subject.share():js',
|
||||
'Subject.shareReplay():js',
|
||||
'Subject.single():js',
|
||||
'Subject.skip():js',
|
||||
'Subject.skipUntil():js',
|
||||
'Subject.startWith():js',
|
||||
'Subject.subscribe():js',
|
||||
'Subject.subscribeOn():js',
|
||||
'Subject.switch():js',
|
||||
'Subject.switchMap():js',
|
||||
'Subject.switchMapTo():js',
|
||||
'Subject.take():js',
|
||||
'Subject.takeUntil():js',
|
||||
'Subject.throttle():js',
|
||||
'Subject.timeout():js',
|
||||
'Subject.timeoutWith():js',
|
||||
'Subject.toArray():js',
|
||||
'Subject.toPromise():js',
|
||||
'Subject.unsubscribe():js',
|
||||
'Subject.window():js',
|
||||
'Subject.windowCount():js',
|
||||
'Subject.windowTime():js',
|
||||
'Subject.windowToggle():js',
|
||||
'Subject.windowWhen():js',
|
||||
'Subject.withLatestFrom():js',
|
||||
'Subject.zip():js',
|
||||
'Subject.zipAll():js',
|
||||
|
||||
|
||||
'OutputMetadata',
|
||||
'OutputMetadata.bindingPropertyName',
|
||||
'ExpressionChangedAfterItHasBeenCheckedException',
|
||||
|
@ -839,8 +1035,6 @@ var NG_API = [
|
|||
'NoProviderError.message=',
|
||||
'NoProviderError.stackTrace',
|
||||
'NumberPipe',
|
||||
'Observable.observer():js',
|
||||
'Observable:js',
|
||||
'ObservableListDiff.check():dart',
|
||||
'ObservableListDiff.collection:dart',
|
||||
'ObservableListDiff.diff():dart',
|
||||
|
|
|
@ -51,7 +51,7 @@ import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
|
|||
|
||||
var cmpInstanceCount;
|
||||
var log: string[];
|
||||
var eventBus: EventEmitter;
|
||||
var eventBus: EventEmitter<any>;
|
||||
var completer: PromiseCompleter<any>;
|
||||
|
||||
export function main() {
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'dart:core';
|
|||
import 'dart:async';
|
||||
import "package:angular2/src/core/facade/async.dart";
|
||||
|
||||
class MockEventEmitter extends EventEmitter {
|
||||
class MockEventEmitter<T> extends EventEmitter<T> {
|
||||
final controller = new StreamController.broadcast(sync: true);
|
||||
|
||||
@override
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {EventEmitter} from 'angular2/src/core/facade/async';
|
||||
|
||||
export class MockEventEmitter extends EventEmitter {
|
||||
export class MockEventEmitter<T> extends EventEmitter<T> {
|
||||
private _nextFns: Function[] = [];
|
||||
|
||||
constructor() { super(); }
|
||||
|
||||
observer(generator: any): any {
|
||||
subscribe(generator: any): any {
|
||||
this._nextFns.push(generator.next);
|
||||
return new MockDisposable();
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
|||
* Such that whatever goes into one's sink comes out the others source.
|
||||
*/
|
||||
export function createPairedMessageBuses(): PairedMessageBuses {
|
||||
var firstChannels: {[key: string]: MockEventEmitter} = {};
|
||||
var firstChannels: {[key: string]: MockEventEmitter<any>} = {};
|
||||
var workerMessageBusSink = new MockMessageBusSink(firstChannels);
|
||||
var uiMessageBusSource = new MockMessageBusSource(firstChannels);
|
||||
|
||||
var secondChannels: {[key: string]: MockEventEmitter} = {};
|
||||
var secondChannels: {[key: string]: MockEventEmitter<any>} = {};
|
||||
var uiMessageBusSink = new MockMessageBusSink(secondChannels);
|
||||
var workerMessageBusSource = new MockMessageBusSource(secondChannels);
|
||||
|
||||
|
@ -30,7 +30,7 @@ export class PairedMessageBuses {
|
|||
}
|
||||
|
||||
export class MockMessageBusSource implements MessageBusSource {
|
||||
constructor(private _channels: {[key: string]: MockEventEmitter}) {}
|
||||
constructor(private _channels: {[key: string]: MockEventEmitter<any>}) {}
|
||||
|
||||
initChannel(channel: string, runInZone = true) {
|
||||
if (!StringMapWrapper.contains(this._channels, channel)) {
|
||||
|
@ -38,7 +38,7 @@ export class MockMessageBusSource implements MessageBusSource {
|
|||
}
|
||||
}
|
||||
|
||||
from(channel: string): MockEventEmitter {
|
||||
from(channel: string): MockEventEmitter<any> {
|
||||
if (!StringMapWrapper.contains(this._channels, channel)) {
|
||||
throw new BaseException(`${channel} is not set up. Did you forget to call initChannel?`);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ export class MockMessageBusSource implements MessageBusSource {
|
|||
}
|
||||
|
||||
export class MockMessageBusSink implements MessageBusSink {
|
||||
constructor(private _channels: {[key: string]: MockEventEmitter}) {}
|
||||
constructor(private _channels: {[key: string]: MockEventEmitter<any>}) {}
|
||||
|
||||
initChannel(channel: string, runInZone = true) {
|
||||
if (!StringMapWrapper.contains(this._channels, channel)) {
|
||||
|
@ -57,7 +57,7 @@ export class MockMessageBusSink implements MessageBusSink {
|
|||
}
|
||||
}
|
||||
|
||||
to(channel: string): MockEventEmitter {
|
||||
to(channel: string): MockEventEmitter<any> {
|
||||
if (!StringMapWrapper.contains(this._channels, channel)) {
|
||||
this._channels[channel] = new MockEventEmitter();
|
||||
}
|
||||
|
@ -79,9 +79,9 @@ export class MockMessageBus extends MessageBus {
|
|||
this.source.initChannel(channel, runInZone);
|
||||
}
|
||||
|
||||
to(channel: string): MockEventEmitter { return this.sink.to(channel); }
|
||||
to(channel: string): MockEventEmitter<any> { return this.sink.to(channel); }
|
||||
|
||||
from(channel: string): MockEventEmitter { return this.source.from(channel); }
|
||||
from(channel: string): MockEventEmitter<any> { return this.source.from(channel); }
|
||||
|
||||
attachToZone(zone: NgZone) {}
|
||||
}
|
||||
|
|
|
@ -71,8 +71,8 @@ export class MdInput {
|
|||
|
||||
// Events emitted by this directive. We use these special 'md-' events to communicate
|
||||
// to the parent MdInputContainer.
|
||||
mdChange: EventEmitter;
|
||||
mdFocusChange: EventEmitter;
|
||||
mdChange: EventEmitter<any>;
|
||||
mdFocusChange: EventEmitter<any>;
|
||||
|
||||
constructor(@Attribute('value') value: string, @SkipSelf() @Host() container: MdInputContainer,
|
||||
@Attribute('id') id: string) {
|
||||
|
|
|
@ -68,7 +68,7 @@ export class MdRadioGroup implements OnChanges {
|
|||
/** The ID of the selected radio button. */
|
||||
selectedRadioId: string;
|
||||
|
||||
change: EventEmitter;
|
||||
change: EventEmitter<any>;
|
||||
|
||||
tabindex: number;
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import {ObservableWrapper} from 'angular2/src/core/facade/async';
|
|||
export class Zippy {
|
||||
visible: boolean = true;
|
||||
title: string = '';
|
||||
openHandler: EventEmitter = new EventEmitter();
|
||||
closeHandler: EventEmitter = new EventEmitter();
|
||||
openHandler: EventEmitter<any> = new EventEmitter();
|
||||
closeHandler: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
toggle() {
|
||||
this.visible = !this.visible;
|
||||
|
|
|
@ -149,7 +149,7 @@ export class DowngradeNg2ComponentAdapter {
|
|||
}
|
||||
var emitter = this.component[output.prop];
|
||||
if (emitter) {
|
||||
emitter.observer({
|
||||
emitter.subscribe({
|
||||
next: assignExpr ? ((setter) => (value) => setter(this.scope, value))(setter) :
|
||||
((getter) => (value) => getter(this.scope, {$event: value}))(getter)
|
||||
});
|
||||
|
|
|
@ -244,7 +244,7 @@ class UpgradeNg1ComponentAdapter implements OnChanges, DoCheck {
|
|||
if (typeof value == 'number' && isNaN(value) && typeof last == 'number' && isNaN(last)) {
|
||||
// ignore because NaN != NaN
|
||||
} else {
|
||||
var eventEmitter: EventEmitter = this[this.propOuts[i]];
|
||||
var eventEmitter: EventEmitter<any> = this[this.propOuts[i]];
|
||||
eventEmitter.next(lastValues[i] = value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@reactivex/rxjs": {
|
||||
"version": "5.0.0-alpha.4"
|
||||
"version": "5.0.0-alpha.6"
|
||||
},
|
||||
"angular": {
|
||||
"version": "1.4.7"
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
"version": "2.0.0-alpha.44",
|
||||
"dependencies": {
|
||||
"@reactivex/rxjs": {
|
||||
"version": "5.0.0-alpha.4",
|
||||
"from": "https://registry.npmjs.org/@reactivex/rxjs/-/rxjs-5.0.0-alpha.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@reactivex/rxjs/-/rxjs-5.0.0-alpha.4.tgz"
|
||||
"version": "5.0.0-alpha.6",
|
||||
"from": "@reactivex/rxjs@5.0.0-alpha.6",
|
||||
"resolved": "http://registry.npmjs.org/@reactivex/rxjs/-/rxjs-5.0.0-alpha.6.tgz"
|
||||
},
|
||||
"angular": {
|
||||
"version": "1.4.7",
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"test": "gulp test.all.js && gulp test.all.dart"
|
||||
},
|
||||
"dependencies": {
|
||||
"@reactivex/rxjs": "5.0.0-alpha.4",
|
||||
"@reactivex/rxjs": "5.0.0-alpha.6",
|
||||
"reflect-metadata": "0.1.2",
|
||||
"zone.js": "0.5.8"
|
||||
},
|
||||
|
|
|
@ -230,6 +230,8 @@ class CustomLanguageServiceHost implements ts.LanguageServiceHost {
|
|||
} else if (this.compilerOptions.moduleResolution === ts.ModuleResolutionKind.NodeJs &&
|
||||
tsFilePath.match(/^node_modules/)) {
|
||||
absoluteTsFilePath = path.resolve(tsFilePath);
|
||||
} else if (tsFilePath.match(/^@reactivex/)) {
|
||||
absoluteTsFilePath = path.resolve('node_modules', tsFilePath);
|
||||
} else {
|
||||
absoluteTsFilePath = path.join(this.treeInputPath, tsFilePath);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue