refactor(platform-webworker): misc cleanup

This commit is contained in:
Victor Berchet 2017-02-16 14:09:06 -08:00
parent 1bdf7061b8
commit f38dbfbd64
16 changed files with 83 additions and 123 deletions

View File

@ -29,9 +29,10 @@ export {platformWorkerUi} from './worker_render';
export function bootstrapWorkerUi(
workerScriptUri: string, customProviders: Provider[] = []): Promise<PlatformRef> {
// For now, just creates the worker ui platform...
return Promise.resolve(platformWorkerUi(([{
provide: WORKER_SCRIPT,
useValue: workerScriptUri,
}] as Provider[])
.concat(customProviders)));
const platform = platformWorkerUi([
{provide: WORKER_SCRIPT, useValue: workerScriptUri},
...customProviders,
]);
return Promise.resolve(platform);
}

View File

@ -13,8 +13,6 @@ export const RenderDebugInfo: typeof r.RenderDebugInfo = r.RenderDebugInfo;
export const ReflectionCapabilities: typeof r.ReflectionCapabilities = r.ReflectionCapabilities;
export type DebugDomRootRenderer = typeof r._DebugDomRootRenderer;
export const DebugDomRootRenderer: typeof r.DebugDomRootRenderer = r.DebugDomRootRenderer;
export const reflector: typeof r.reflector = r.reflector;
export type NoOpAnimationPlayer = typeof r._NoOpAnimationPlayer;

View File

@ -8,4 +8,4 @@
import {InjectionToken} from '@angular/core';
export const ON_WEB_WORKER = new InjectionToken('WebWorker.onWebWorker');
export const ON_WEB_WORKER = new InjectionToken<boolean>('WebWorker.onWebWorker');

View File

@ -9,7 +9,7 @@
import {Injectable, Type} from '@angular/core';
import {EventEmitter} from '../../facade/async';
import {isPresent, print, stringify} from '../../facade/lang';
import {stringify} from '../../facade/lang';
import {MessageBus} from './message_bus';
import {Serializer} from './serializer';
@ -55,13 +55,12 @@ interface PromiseCompleter {
}
export class ClientMessageBroker_ extends ClientMessageBroker {
private _pending: Map<string, PromiseCompleter> = new Map<string, PromiseCompleter>();
private _pending = new Map<string, PromiseCompleter>();
private _sink: EventEmitter<any>;
/** @internal */
public _serializer: Serializer;
constructor(
messageBus: MessageBus, _serializer: Serializer, public channel: any /** TODO #9100 */) {
constructor(messageBus: MessageBus, _serializer: Serializer, public channel: any) {
super();
this._sink = messageBus.to(channel);
this._serializer = _serializer;
@ -74,7 +73,7 @@ export class ClientMessageBroker_ extends ClientMessageBroker {
const time: string = stringify(new Date().getTime());
let iteration: number = 0;
let id: string = name + time + stringify(iteration);
while (isPresent((this as any /** TODO #9100 */)._pending[id])) {
while (this._pending.has(id)) {
id = `${name}${time}${iteration}`;
iteration++;
}
@ -82,8 +81,8 @@ export class ClientMessageBroker_ extends ClientMessageBroker {
}
runOnService(args: UiArguments, returnType: Type<any>): Promise<any> {
const fnArgs: any[] /** TODO #9100 */ = [];
if (isPresent(args.args)) {
const fnArgs: any[] = [];
if (args.args) {
args.args.forEach(argument => {
if (argument.type != null) {
fnArgs.push(this._serializer.serialize(argument.value, argument.type));
@ -100,26 +99,26 @@ export class ClientMessageBroker_ extends ClientMessageBroker {
promise = new Promise((resolve, reject) => { completer = {resolve, reject}; });
id = this._generateMessageId(args.method);
this._pending.set(id, completer);
promise.catch((err) => {
print(err);
if (console && console.log) {
// tslint:disable-next-line:no-console
console.log(err);
}
completer.reject(err);
});
promise = promise.then((value: any) => {
if (this._serializer == null) {
return value;
} else {
return this._serializer.deserialize(value, returnType);
}
});
promise = promise.then(
(value: any) =>
this._serializer ? value : this._serializer.deserialize(value, returnType));
} else {
promise = null;
}
// TODO(jteplitz602): Create a class for these messages so we don't keep using StringMap #3685
const message = {'method': args.method, 'args': fnArgs};
if (id != null) {
(message as any /** TODO #9100 */)['id'] = id;
(message as any)['id'] = id;
}
this._sink.emit(message);
@ -128,7 +127,6 @@ export class ClientMessageBroker_ extends ClientMessageBroker {
private _handleMessage(message: {[key: string]: any}): void {
const data = new MessageData(message);
// TODO(jteplitz602): replace these strings with messaging constants #3685
if (data.type === 'result' || data.type === 'error') {
const id = data.id;
if (this._pending.has(id)) {
@ -167,7 +165,7 @@ class MessageData {
* @experimental WebWorker support in Angular is experimental.
*/
export class FnArg {
constructor(public value: any /** TODO #9100 */, public type: Type<any>) {}
constructor(public value: any, public type: Type<any>) {}
}
/**

View File

@ -10,14 +10,9 @@ import {Injectable} from '@angular/core';
@Injectable()
export class RenderStore {
private _nextIndex: number = 0;
private _lookupById: Map<number, any>;
private _lookupByObject: Map<any, number>;
constructor() {
this._lookupById = new Map<number, any>();
this._lookupByObject = new Map<any, number>();
}
private _nextIndex = 0;
private _lookupById = new Map<number, any>();
private _lookupByObject = new Map<any, number>();
allocateId(): number { return this._nextIndex++; }
@ -33,21 +28,8 @@ export class RenderStore {
}
deserialize(id: number): any {
if (id == null) {
return null;
}
if (!this._lookupById.has(id)) {
return null;
}
return this._lookupById.get(id);
return id == null || !this._lookupById.has(id) ? null : this._lookupById.get(id);
}
serialize(obj: any): number {
if (obj == null) {
return null;
}
return this._lookupByObject.get(obj);
}
serialize(obj: any): number { return obj == null ? null : this._lookupByObject.get(obj); }
}

View File

@ -8,7 +8,7 @@
import {Injectable, RenderComponentType, Type, ViewEncapsulation} from '@angular/core';
import {isPresent} from '../../facade/lang';
import {stringify} from '../../facade/lang';
import {RenderStore} from './render_store';
import {LocationType} from './serialized_types';
@ -25,11 +25,11 @@ export class Serializer {
constructor(private _renderStore: RenderStore) {}
serialize(obj: any, type: any): Object {
if (!isPresent(obj)) {
if (obj == null) {
return null;
}
if (Array.isArray(obj)) {
return (<any[]>obj).map(v => this.serialize(v, type));
return obj.map(v => this.serialize(v, type));
}
if (type == PRIMITIVE) {
return obj;
@ -46,16 +46,16 @@ export class Serializer {
if (type === LocationType) {
return this._serializeLocation(obj);
}
throw new Error('No serializer for ' + type.toString());
throw new Error(`No serializer for type ${stringify}`);
}
deserialize(map: any, type: any, data?: any): any {
if (!isPresent(map)) {
if (map == null) {
return null;
}
if (Array.isArray(map)) {
return (<any[]>map).map(val => this.deserialize(val, type, data));
return map.map(val => this.deserialize(val, type, data));
}
if (type === PRIMITIVE) {
@ -91,7 +91,7 @@ export class Serializer {
'pathname': loc.pathname,
'search': loc.search,
'hash': loc.hash,
'origin': loc.origin
'origin': loc.origin,
};
}
@ -107,7 +107,7 @@ export class Serializer {
'templateUrl': obj.templateUrl,
'slotCount': obj.slotCount,
'encapsulation': this.serialize(obj.encapsulation, ViewEncapsulation),
'styles': this.serialize(obj.styles, PRIMITIVE)
'styles': this.serialize(obj.styles, PRIMITIVE),
};
}

View File

@ -56,9 +56,7 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker {
private _sink: EventEmitter<any>;
private _methods: Map<string, Function> = new Map<string, Function>();
constructor(
messageBus: MessageBus, private _serializer: Serializer,
public channel: any /** TODO #9100 */) {
constructor(messageBus: MessageBus, private _serializer: Serializer, public channel: string) {
super();
this._sink = messageBus.to(channel);
const source = messageBus.from(channel);
@ -71,14 +69,14 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker {
this._methods.set(methodName, (message: ReceivedMessage) => {
const serializedArgs = message.args;
const numArgs = signature === null ? 0 : signature.length;
const deserializedArgs: any[] = new Array(numArgs);
const deserializedArgs = new Array(numArgs);
for (let i = 0; i < numArgs; i++) {
const serializedArg = serializedArgs[i];
deserializedArgs[i] = this._serializer.deserialize(serializedArg, signature[i]);
}
const promise = method(...deserializedArgs);
if (isPresent(returnType) && promise) {
if (returnType && promise) {
this._wrapWebWorkerPromise(message.id, promise, returnType);
}
});
@ -93,8 +91,11 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker {
private _wrapWebWorkerPromise(id: string, promise: Promise<any>, type: Type<any>): void {
promise.then((result: any) => {
this._sink.emit(
{'type': 'result', 'value': this._serializer.serialize(result, type), 'id': id});
this._sink.emit({
'type': 'result',
'value': this._serializer.serialize(result, type),
'id': id,
});
});
}
}

View File

@ -17,13 +17,13 @@ export class EventDispatcher {
this._sink.emit({
'element': this._serializer.serialize(element, RenderStoreObject),
'animationPlayer': this._serializer.serialize(player, RenderStoreObject),
'phaseName': phaseName
'phaseName': phaseName,
});
return true;
}
dispatchRenderEvent(element: any, eventTarget: string, eventName: string, event: any): boolean {
let serializedEvent: any /** TODO #9100 */;
let serializedEvent: any;
// TODO (jteplitz602): support custom events #3350
switch (event.type) {
case 'click':
@ -109,7 +109,7 @@ export class EventDispatcher {
'element': this._serializer.serialize(element, RenderStoreObject),
'eventName': eventName,
'eventTarget': eventTarget,
'event': serializedEvent
'event': serializedEvent,
});
// TODO(kegluneq): Eventually, we want the user to indicate from the UI side whether the event

View File

@ -61,10 +61,10 @@ function addTarget(e: Event, serializedEvent: {[key: string]: any}): {[key: stri
}
function serializeEvent(e: any, properties: string[]): {[key: string]: any} {
const serialized = {};
const serialized: {[k: string]: any} = {};
for (let i = 0; i < properties.length; i++) {
const prop = properties[i];
(serialized as any /** TODO #9100 */)[prop] = e[prop];
serialized[prop] = e[prop];
}
return serialized;
}

View File

@ -229,18 +229,16 @@ export class MessageBasedRenderer {
private _listen(renderer: Renderer, renderElement: any, eventName: string, unlistenId: number) {
const unregisterCallback = renderer.listen(
renderElement, eventName,
(event: any /** TODO #9100 */) =>
this._eventDispatcher.dispatchRenderEvent(renderElement, null, eventName, event));
renderElement, eventName, (event: any) => this._eventDispatcher.dispatchRenderEvent(
renderElement, null, eventName, event));
this._renderStore.store(unregisterCallback, unlistenId);
}
private _listenGlobal(
renderer: Renderer, eventTarget: string, eventName: string, unlistenId: number) {
const unregisterCallback = renderer.listenGlobal(
eventTarget, eventName,
(event: any /** TODO #9100 */) =>
this._eventDispatcher.dispatchRenderEvent(null, eventTarget, eventName, event));
eventTarget, eventName, (event: any) => this._eventDispatcher.dispatchRenderEvent(
null, eventTarget, eventName, event));
this._renderStore.store(unregisterCallback, unlistenId);
}

View File

@ -7,24 +7,23 @@
*/
import {PlatformLocation} from '@angular/common';
import {APP_INITIALIZER, InjectionToken, NgZone} from '@angular/core';
import {APP_INITIALIZER, NgZone} from '@angular/core';
import {WebWorkerPlatformLocation} from './platform_location';
/**
* Those providers should be added when the router is used in a worker context in addition to the
* {@link ROUTER_PROVIDERS} and after them.
* @experimental
*/
export const WORKER_APP_LOCATION_PROVIDERS = [
{provide: PlatformLocation, useClass: WebWorkerPlatformLocation}, {
{provide: PlatformLocation, useClass: WebWorkerPlatformLocation},
{
provide: APP_INITIALIZER,
useFactory: appInitFnFactory,
multi: true,
deps: [PlatformLocation, NgZone]
}
},
];
function appInitFnFactory(platformLocation: WebWorkerPlatformLocation, zone: NgZone): () =>

View File

@ -43,7 +43,7 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
listeners = this._hashChangeListeners;
}
if (listeners !== null) {
if (listeners) {
const e = deserializeGenericEvent(msg['event']);
// There was a popState or hashChange event, so the location object thas been updated
this._location = this._serializer.deserialize(msg['location'], LocationType);
@ -58,14 +58,13 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
init(): Promise<boolean> {
const args: UiArguments = new UiArguments('getLocation');
const locationPromise: Promise<LocationType> = this._broker.runOnService(args, LocationType);
return locationPromise.then(
(val: LocationType):
boolean => {
return this._broker.runOnService(args, LocationType)
.then(
(val: LocationType) => {
this._location = val;
return true;
},
(err): boolean => { throw new Error(err); });
err => { throw new Error(err); });
}
getBaseHrefFromDOM(): string {
@ -77,29 +76,11 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
onHashChange(fn: LocationChangeListener): void { this._hashChangeListeners.push(fn); }
get pathname(): string {
if (this._location === null) {
return null;
}
get pathname(): string { return this._location ? this._location.pathname : null; }
return this._location.pathname;
}
get search(): string { return this._location ? this._location.search : null; }
get search(): string {
if (this._location === null) {
return null;
}
return this._location.search;
}
get hash(): string {
if (this._location === null) {
return null;
}
return this._location.hash;
}
get hash(): string { return this._location ? this._location.hash : null; }
set pathname(newPath: string) {
if (this._location === null) {

View File

@ -9,7 +9,6 @@
import {Injectable, RenderComponentType, Renderer, RootRenderer, ViewEncapsulation} from '@angular/core';
import {ListWrapper} from '../../facade/collection';
import {isPresent} from '../../facade/lang';
import {AnimationKeyframe, AnimationPlayer, AnimationStyles, RenderDebugInfo} from '../../private_import_core';
import {ClientMessageBrokerFactory, FnArg, UiArguments} from '../shared/client_message_broker';
import {MessageBus} from '../shared/message_bus';
@ -21,7 +20,7 @@ import {deserializeGenericEvent} from './event_deserializer';
@Injectable()
export class WebWorkerRootRenderer implements RootRenderer {
private _messageBroker: any /** TODO #9100 */;
private _messageBroker: ClientMessageBroker;
public globalEvents: NamedEventEmitter = new NamedEventEmitter();
private _componentRenderers: Map<string, WebWorkerRenderer> =
new Map<string, WebWorkerRenderer>();
@ -39,6 +38,7 @@ export class WebWorkerRootRenderer implements RootRenderer {
const element =
<WebWorkerRenderNode>this._serializer.deserialize(message['element'], RenderStoreObject);
const playerData = message['animationPlayer'];
if (playerData) {
const phaseName = message['phaseName'];
const player = <AnimationPlayer>this._serializer.deserialize(playerData, RenderStoreObject);
@ -47,7 +47,7 @@ export class WebWorkerRootRenderer implements RootRenderer {
const eventName = message['eventName'];
const target = message['eventTarget'];
const event = deserializeGenericEvent(message['event']);
if (isPresent(target)) {
if (target) {
this.globalEvents.dispatchEvent(eventNameWithTarget(target, eventName), event);
} else {
element.events.dispatchEvent(eventName, event);

View File

@ -8,8 +8,6 @@
import {DomAdapter, setRootDomAdapter} from '../../private_import_platform-browser';
/**
* This adapter is required to log error messages.
*

View File

@ -61,16 +61,23 @@ export function setupWebWorker(): void {
*/
@NgModule({
providers: [
BROWSER_SANITIZATION_PROVIDERS, Serializer, {provide: DOCUMENT, useValue: null},
BROWSER_SANITIZATION_PROVIDERS,
Serializer,
{provide: DOCUMENT, useValue: null},
{provide: ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_},
{provide: ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_},
WebWorkerRootRenderer, {provide: RootRenderer, useExisting: WebWorkerRootRenderer},
{provide: ON_WEB_WORKER, useValue: true}, RenderStore,
WebWorkerRootRenderer,
{provide: RootRenderer, useExisting: WebWorkerRootRenderer},
{provide: ON_WEB_WORKER, useValue: true},
RenderStore,
{provide: ErrorHandler, useFactory: errorHandler, deps: []},
{provide: MessageBus, useFactory: createMessageBus, deps: [NgZone]},
{provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}
{provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true},
],
exports: [CommonModule, ApplicationModule]
exports: [
CommonModule,
ApplicationModule,
]
})
export class WorkerAppModule {
}

View File

@ -88,7 +88,7 @@ export const _WORKER_UI_PLATFORM_PROVIDERS: Provider[] = [
multi: true,
deps: [Injector]
},
{provide: MessageBus, useFactory: messageBusFactory, deps: [WebWorkerInstance]}
{provide: MessageBus, useFactory: messageBusFactory, deps: [WebWorkerInstance]},
];
function initializeGenericWorkerRenderer(injector: Injector) {
@ -155,8 +155,5 @@ function spawnWebWorker(uri: string, instance: WebWorkerInstance): void {
}
function _resolveDefaultAnimationDriver(): AnimationDriver {
if (getDOM().supportsWebAnimation()) {
return new WebAnimationsDriver();
}
return AnimationDriver.NOOP;
return getDOM().supportsWebAnimation() ? new WebAnimationsDriver() : AnimationDriver.NOOP;
}