diff --git a/modules/angular2/src/web_workers/shared/client_message_broker.ts b/modules/angular2/src/web_workers/shared/client_message_broker.ts index 90702b603b..c3d53126cf 100644 --- a/modules/angular2/src/web_workers/shared/client_message_broker.ts +++ b/modules/angular2/src/web_workers/shared/client_message_broker.ts @@ -12,6 +12,7 @@ import {ListWrapper, StringMapWrapper, MapWrapper} from "angular2/src/core/facad import {Serializer} from "angular2/src/web_workers/shared/serializer"; import {Injectable} from "angular2/di"; import {Type, StringWrapper} from "angular2/src/core/facade/lang"; +export {Type} from "angular2/src/core/facade/lang"; @Injectable() export class ClientMessageBrokerFactory { @@ -29,7 +30,8 @@ export class ClientMessageBroker { constructor(messageBus: MessageBus, protected _serializer: Serializer, public channel) { this._sink = messageBus.to(channel); var source = messageBus.from(channel); - ObservableWrapper.subscribe(source, (message) => this._handleMessage(message)); + ObservableWrapper.subscribe(source, + (message: StringMap) => this._handleMessage(message)); } private _generateMessageId(name: string): string { @@ -43,7 +45,7 @@ export class ClientMessageBroker { return id; } - runOnUiThread(args: UiArguments, returnType: Type): Promise { + runOnService(args: UiArguments, returnType: Type): Promise { var fnArgs = []; if (isPresent(args.args)) { ListWrapper.forEach(args.args, (argument) => { @@ -128,7 +130,7 @@ class MessageData { } export class FnArg { - constructor(public value, public type) {} + constructor(public value, public type: Type) {} } export class UiArguments { diff --git a/modules/angular2/src/web_workers/ui/application.dart b/modules/angular2/src/web_workers/ui/application.dart index 9fb758d9b2..be70e2485e 100644 --- a/modules/angular2/src/web_workers/ui/application.dart +++ b/modules/angular2/src/web_workers/ui/application.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'dart:core'; import 'package:angular2/src/web_workers/shared/message_bus.dart' show MessageBus; -import 'package:angular2/src/web_workers/ui/impl.dart' show bootstrapUICommon; +import 'package:angular2/src/web_workers/ui/impl.dart' show bootstrapUICommon, WebWorkerApplication; import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart'; /** @@ -14,26 +14,24 @@ import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart'; * You instantiate a WebWorker application by calling bootstrap with the URI of your worker's index script * Note: The WebWorker script must call bootstrapWebworker once it is set up to complete the bootstrapping process */ -Future bootstrap(String uri) { - return spawnWebWorker(Uri.parse(uri)).then((bus) { - bootstrapUICommon(bus); - return bus; - }); +Future bootstrap(String uri) async { + var instance = await spawnWebWorker(Uri.parse(uri)); + instance.app = bootstrapUICommon(instance.bus); + return instance; } /** * To be called from the main thread to spawn and communicate with the worker thread */ -Future spawnWebWorker(Uri uri) { +Future spawnWebWorker(Uri uri) async { var receivePort = new ReceivePort(); var isolateEndSendPort = receivePort.sendPort; - return Isolate.spawnUri(uri, const [], isolateEndSendPort).then((_) { - var source = new UIMessageBusSource(receivePort); - return source.sink.then((sendPort) { - var sink = new IsolateMessageBusSink(sendPort); - return new IsolateMessageBus(sink, source); - }); - }); + var isolate = await Isolate.spawnUri(uri, const [], isolateEndSendPort); + var source = new UIMessageBusSource(receivePort); + var sendPort = await source.sink; + var sink = new IsolateMessageBusSink(sendPort); + var bus = new IsolateMessageBus(sink, source); + return new IsolateInstance(null, isolate, bus); } class UIMessageBusSource extends IsolateMessageBusSource { @@ -43,3 +41,15 @@ class UIMessageBusSource extends IsolateMessageBusSource { return message is SendPort; }); } + +/** + * Wrapper class that exposes the {@link WebWorkerApplication} + * Isolate instance and underyling {@link MessageBus} for lower level message passing. + */ +class IsolateInstance { + WebWorkerApplication app; + final Isolate isolate; + final MessageBus bus; + + IsolateInstance(this.app, this.isolate, this.bus); +} diff --git a/modules/angular2/src/web_workers/ui/application.ts b/modules/angular2/src/web_workers/ui/application.ts index d350adbd03..9f5014b0d7 100644 --- a/modules/angular2/src/web_workers/ui/application.ts +++ b/modules/angular2/src/web_workers/ui/application.ts @@ -4,8 +4,9 @@ import { PostMessageBusSource } from 'angular2/src/web_workers/shared/post_message_bus'; import {MessageBus} from 'angular2/src/web_workers/shared/message_bus'; -import {BaseException} from "angular2/src/core/facade/lang"; -import {bootstrapUICommon} from "angular2/src/web_workers/ui/impl"; +import {BaseException} from 'angular2/src/core/facade/lang'; +import {bootstrapUICommon, WebWorkerApplication} from 'angular2/src/web_workers/ui/impl'; +export {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl'; export * from 'angular2/src/web_workers/shared/message_bus'; /** @@ -16,15 +17,24 @@ export * from 'angular2/src/web_workers/shared/message_bus'; * Note: The WebWorker script must call bootstrapWebworker once it is set up to complete the * bootstrapping process */ -export function bootstrap(uri: string): MessageBus { - var messageBus = spawnWebWorker(uri); - bootstrapUICommon(messageBus); - return messageBus; +export function bootstrap(uri: string): WebWorkerInstance { + var instance = spawnWebWorker(uri); + instance.app = bootstrapUICommon(instance.bus); + return instance; } -export function spawnWebWorker(uri: string): MessageBus { +export function spawnWebWorker(uri: string): WebWorkerInstance { var webWorker: Worker = new Worker(uri); var sink = new PostMessageBusSink(webWorker); var source = new PostMessageBusSource(webWorker); - return new PostMessageBus(sink, source); + var bus = new PostMessageBus(sink, source); + return new WebWorkerInstance(null, webWorker, bus); +} + +/** + * Wrapper class that exposes the {@link WebWorkerApplication} + * Isolate instance and underyling {@link MessageBus} for lower level message passing. + */ +export class WebWorkerInstance { + constructor(public app: WebWorkerApplication, public worker: Worker, public bus: MessageBus) {} } diff --git a/modules/angular2/src/web_workers/ui/di_bindings.ts b/modules/angular2/src/web_workers/ui/di_bindings.ts index b22ea16bae..13d1a5fe59 100644 --- a/modules/angular2/src/web_workers/ui/di_bindings.ts +++ b/modules/angular2/src/web_workers/ui/di_bindings.ts @@ -2,7 +2,6 @@ // There should be a way to refactor application so that this file is unnecessary. See #3277 import {Injector, bind, Binding} from "angular2/di"; import {Reflector, reflector} from 'angular2/src/core/reflection/reflection'; -import {ListWrapper} from 'angular2/src/core/facade/collection'; import { Parser, Lexer, @@ -61,13 +60,14 @@ import { RenderViewWithFragmentsStore } from 'angular2/src/web_workers/shared/render_view_with_fragments_store'; import {AnchorBasedAppRootUrl} from 'angular2/src/core/services/anchor_based_app_root_url'; -import {WebWorkerMain} from 'angular2/src/web_workers/ui/impl'; +import {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl'; import {MessageBus} from 'angular2/src/web_workers/shared/message_bus'; import {MessageBasedRenderCompiler} from 'angular2/src/web_workers/ui/render_compiler'; import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer'; import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl'; import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup'; import {ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/service_message_broker'; +import {ClientMessageBrokerFactory} from 'angular2/src/web_workers/shared/client_message_broker'; var _rootInjector: Injector; @@ -134,12 +134,13 @@ function _injectorBindings(): any[] { Testability, AnchorBasedAppRootUrl, bind(AppRootUrl).toAlias(AnchorBasedAppRootUrl), - WebWorkerMain, + WebWorkerApplication, WebWorkerSetup, MessageBasedRenderCompiler, MessageBasedXHRImpl, MessageBasedRenderer, - ServiceMessageBrokerFactory + ServiceMessageBrokerFactory, + ClientMessageBrokerFactory ]; } diff --git a/modules/angular2/src/web_workers/ui/impl.ts b/modules/angular2/src/web_workers/ui/impl.ts index 9e45648112..e68c2a18f2 100644 --- a/modules/angular2/src/web_workers/ui/impl.ts +++ b/modules/angular2/src/web_workers/ui/impl.ts @@ -15,25 +15,43 @@ import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup'; import {MessageBasedRenderCompiler} from 'angular2/src/web_workers/ui/render_compiler'; import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer'; import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl'; +import { + ClientMessageBrokerFactory, + ClientMessageBroker, +} from 'angular2/src/web_workers/shared/client_message_broker'; +import { + ServiceMessageBrokerFactory, + ServiceMessageBroker +} from 'angular2/src/web_workers/shared/service_message_broker'; /** * Creates a zone, sets up the DI bindings * And then creates a new WebWorkerMain object to handle messages from the worker */ -export function bootstrapUICommon(bus: MessageBus) { +export function bootstrapUICommon(bus: MessageBus): WebWorkerApplication { BrowserDomAdapter.makeCurrent(); var zone = createNgZone(); wtfInit(); - zone.run(() => { + return zone.run(() => { var injector = createInjector(zone, bus); - // necessary to kick off all the message based components - injector.get(WebWorkerMain); + injector.get(MessageBasedRenderCompiler).start(); + injector.get(MessageBasedRenderer).start(); + injector.get(MessageBasedXHRImpl).start(); + injector.get(WebWorkerSetup).start(); + return injector.get(WebWorkerApplication); }); } @Injectable() -export class WebWorkerMain { - constructor(public renderCompiler: MessageBasedRenderCompiler, - public renderer: MessageBasedRenderer, public xhr: MessageBasedXHRImpl, - public setup: WebWorkerSetup) {} +export class WebWorkerApplication { + constructor(private _clientMessageBrokerFactory: ClientMessageBrokerFactory, + private _serviceMessageBrokerFactory: ServiceMessageBrokerFactory) {} + + createClientMessageBroker(channel: string): ClientMessageBroker { + return this._clientMessageBrokerFactory.createMessageBroker(channel); + } + + createServiceMessageBroker(channel: string): ServiceMessageBroker { + return this._serviceMessageBrokerFactory.createMessageBroker(channel); + } } diff --git a/modules/angular2/src/web_workers/ui/render_compiler.ts b/modules/angular2/src/web_workers/ui/render_compiler.ts index 1812c746ca..8ed6744d70 100644 --- a/modules/angular2/src/web_workers/ui/render_compiler.ts +++ b/modules/angular2/src/web_workers/ui/render_compiler.ts @@ -13,8 +13,11 @@ import {ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/servi @Injectable() export class MessageBasedRenderCompiler { - constructor(brokerFactory: ServiceMessageBrokerFactory, private _renderCompiler: RenderCompiler) { - var broker = brokerFactory.createMessageBroker(RENDER_COMPILER_CHANNEL); + constructor(private _brokerFactory: ServiceMessageBrokerFactory, + private _renderCompiler: RenderCompiler) {} + + start(): void { + var broker = this._brokerFactory.createMessageBroker(RENDER_COMPILER_CHANNEL); broker.registerMethod("compileHost", [RenderDirectiveMetadata], bind(this._renderCompiler.compileHost, this._renderCompiler), ProtoViewDto); diff --git a/modules/angular2/src/web_workers/ui/renderer.ts b/modules/angular2/src/web_workers/ui/renderer.ts index 6ad781f4f9..219e260ef7 100644 --- a/modules/angular2/src/web_workers/ui/renderer.ts +++ b/modules/angular2/src/web_workers/ui/renderer.ts @@ -19,11 +19,13 @@ import {ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/servi @Injectable() export class MessageBasedRenderer { - constructor(brokerFactory: ServiceMessageBrokerFactory, private _bus: MessageBus, + constructor(private _brokerFactory: ServiceMessageBrokerFactory, private _bus: MessageBus, private _serializer: Serializer, private _renderViewWithFragmentsStore: RenderViewWithFragmentsStore, - private _renderer: Renderer) { - var broker = brokerFactory.createMessageBroker(RENDERER_CHANNEL); + private _renderer: Renderer) {} + + start(): void { + var broker = this._brokerFactory.createMessageBroker(RENDERER_CHANNEL); broker.registerMethod("createRootHostView", [RenderProtoViewRef, PRIMITIVE, PRIMITIVE, PRIMITIVE], bind(this._createRootHostView, this)); diff --git a/modules/angular2/src/web_workers/ui/setup.ts b/modules/angular2/src/web_workers/ui/setup.ts index 9e06877f89..c08a78df38 100644 --- a/modules/angular2/src/web_workers/ui/setup.ts +++ b/modules/angular2/src/web_workers/ui/setup.ts @@ -7,14 +7,19 @@ import {StringWrapper} from 'angular2/src/core/facade/lang'; @Injectable() export class WebWorkerSetup { - constructor(bus: MessageBus, anchorBasedAppRootUrl: AnchorBasedAppRootUrl) { - var rootUrl = anchorBasedAppRootUrl.value; - var sink = bus.to(SETUP_CHANNEL); - var source = bus.from(SETUP_CHANNEL); + rootUrl: string; + + constructor(private _bus: MessageBus, anchorBasedAppRootUrl: AnchorBasedAppRootUrl) { + this.rootUrl = anchorBasedAppRootUrl.value; + } + + start(): void { + var sink = this._bus.to(SETUP_CHANNEL); + var source = this._bus.from(SETUP_CHANNEL); ObservableWrapper.subscribe(source, (message: string) => { if (StringWrapper.equals(message, "ready")) { - ObservableWrapper.callNext(sink, {"rootUrl": rootUrl}); + ObservableWrapper.callNext(sink, {"rootUrl": this.rootUrl}); } }); } diff --git a/modules/angular2/src/web_workers/ui/xhr_impl.ts b/modules/angular2/src/web_workers/ui/xhr_impl.ts index 3d92ca9c14..a554fe43ff 100644 --- a/modules/angular2/src/web_workers/ui/xhr_impl.ts +++ b/modules/angular2/src/web_workers/ui/xhr_impl.ts @@ -7,8 +7,10 @@ import {bind} from './bind'; @Injectable() export class MessageBasedXHRImpl { - constructor(brokerFactory: ServiceMessageBrokerFactory, private _xhr: XHR) { - var broker = brokerFactory.createMessageBroker(XHR_CHANNEL); + constructor(private _brokerFactory: ServiceMessageBrokerFactory, private _xhr: XHR) {} + + start(): void { + var broker = this._brokerFactory.createMessageBroker(XHR_CHANNEL); broker.registerMethod("get", [PRIMITIVE], bind(this._xhr.get, this._xhr), PRIMITIVE); } } diff --git a/modules/angular2/src/web_workers/worker/renderer.ts b/modules/angular2/src/web_workers/worker/renderer.ts index a2217883fe..8917c9157d 100644 --- a/modules/angular2/src/web_workers/worker/renderer.ts +++ b/modules/angular2/src/web_workers/worker/renderer.ts @@ -44,7 +44,7 @@ export class WebWorkerCompiler implements RenderCompiler { compileHost(directiveMetadata: RenderDirectiveMetadata): Promise { var fnArgs: FnArg[] = [new FnArg(directiveMetadata, RenderDirectiveMetadata)]; var args: UiArguments = new UiArguments("compileHost", fnArgs); - return this._messageBroker.runOnUiThread(args, ProtoViewDto); + return this._messageBroker.runOnService(args, ProtoViewDto); } /** @@ -55,7 +55,7 @@ export class WebWorkerCompiler implements RenderCompiler { compile(view: ViewDefinition): Promise { var fnArgs: FnArg[] = [new FnArg(view, ViewDefinition)]; var args: UiArguments = new UiArguments("compile", fnArgs); - return this._messageBroker.runOnUiThread(args, ProtoViewDto); + return this._messageBroker.runOnService(args, ProtoViewDto); } /** @@ -71,7 +71,7 @@ export class WebWorkerCompiler implements RenderCompiler { protoViewRefs: Array): Promise { var fnArgs: FnArg[] = [new FnArg(protoViewRefs, RenderProtoViewRef)]; var args: UiArguments = new UiArguments("mergeProtoViewsRecursively", fnArgs); - return this._messageBroker.runOnUiThread(args, RenderProtoViewMergeMapping); + return this._messageBroker.runOnService(args, RenderProtoViewMergeMapping); } } @@ -126,7 +126,7 @@ export class WebWorkerRenderer implements Renderer { fnArgs.push(new FnArg(startIndex, null)); var args = new UiArguments(method, fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); return renderViewWithFragments; } @@ -137,7 +137,7 @@ export class WebWorkerRenderer implements Renderer { destroyView(viewRef: RenderViewRef) { var fnArgs = [new FnArg(viewRef, RenderViewRef)]; var args = new UiArguments("destroyView", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); this._renderViewStore.remove(viewRef); } @@ -151,7 +151,7 @@ export class WebWorkerRenderer implements Renderer { new FnArg(fragmentRef, RenderFragmentRef) ]; var args = new UiArguments("attachFragmentAfterFragment", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -161,7 +161,7 @@ export class WebWorkerRenderer implements Renderer { var fnArgs = [new FnArg(elementRef, WebWorkerElementRef), new FnArg(fragmentRef, RenderFragmentRef)]; var args = new UiArguments("attachFragmentAfterElement", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -170,7 +170,7 @@ export class WebWorkerRenderer implements Renderer { detachFragment(fragmentRef: RenderFragmentRef) { var fnArgs = [new FnArg(fragmentRef, RenderFragmentRef)]; var args = new UiArguments("detachFragment", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -180,7 +180,7 @@ export class WebWorkerRenderer implements Renderer { hydrateView(viewRef: RenderViewRef) { var fnArgs = [new FnArg(viewRef, RenderViewRef)]; var args = new UiArguments("hydrateView", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -190,7 +190,7 @@ export class WebWorkerRenderer implements Renderer { dehydrateView(viewRef: RenderViewRef) { var fnArgs = [new FnArg(viewRef, RenderViewRef)]; var args = new UiArguments("dehydrateView", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -209,7 +209,7 @@ export class WebWorkerRenderer implements Renderer { new FnArg(propertyValue, null) ]; var args = new UiArguments("setElementProperty", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -222,7 +222,7 @@ export class WebWorkerRenderer implements Renderer { new FnArg(attributeValue, null) ]; var args = new UiArguments("setElementAttribute", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -235,7 +235,7 @@ export class WebWorkerRenderer implements Renderer { new FnArg(isAdd, null) ]; var args = new UiArguments("setElementClass", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -248,7 +248,7 @@ export class WebWorkerRenderer implements Renderer { new FnArg(styleValue, null) ]; var args = new UiArguments("setElementStyle", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -262,7 +262,7 @@ export class WebWorkerRenderer implements Renderer { new FnArg(args, null) ]; var uiArgs = new UiArguments("invokeElementMethod", fnArgs); - this._messageBroker.runOnUiThread(uiArgs, null); + this._messageBroker.runOnService(uiArgs, null); } /** @@ -272,7 +272,7 @@ export class WebWorkerRenderer implements Renderer { var fnArgs = [new FnArg(viewRef, RenderViewRef), new FnArg(textNodeIndex, null), new FnArg(text, null)]; var args = new UiArguments("setText", fnArgs); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } /** @@ -282,6 +282,6 @@ export class WebWorkerRenderer implements Renderer { var fnArgs = [new FnArg(viewRef, RenderViewRef)]; var args = new UiArguments("setEventDispatcher", fnArgs); this._eventDispatcher.registerEventDispatcher(viewRef, dispatcher); - this._messageBroker.runOnUiThread(args, null); + this._messageBroker.runOnService(args, null); } } diff --git a/modules/angular2/src/web_workers/worker/xhr_impl.ts b/modules/angular2/src/web_workers/worker/xhr_impl.ts index ae8c09c98c..6978f3938f 100644 --- a/modules/angular2/src/web_workers/worker/xhr_impl.ts +++ b/modules/angular2/src/web_workers/worker/xhr_impl.ts @@ -25,6 +25,6 @@ export class WebWorkerXHRImpl extends XHR { get(url: string): Promise { var fnArgs: FnArg[] = [new FnArg(url, null)]; var args: UiArguments = new UiArguments("get", fnArgs); - return this._messageBroker.runOnUiThread(args, String); + return this._messageBroker.runOnService(args, String); } } diff --git a/modules/angular2/test/web_workers/worker/renderer_integration_spec.ts b/modules/angular2/test/web_workers/worker/renderer_integration_spec.ts index f14c35f5e8..826c9b5ea5 100644 --- a/modules/angular2/test/web_workers/worker/renderer_integration_spec.ts +++ b/modules/angular2/test/web_workers/worker/renderer_integration_spec.ts @@ -43,7 +43,7 @@ import { DomProtoView } from 'angular2/src/core/render/dom/view/proto_view'; import {someComponent} from '../../core/render/dom/dom_renderer_integration_spec'; -import {WebWorkerMain} from 'angular2/src/web_workers/ui/impl'; +import {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl'; import {MessageBasedRenderCompiler} from 'angular2/src/web_workers/ui/render_compiler'; import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer'; import {createPairedMessageBuses} from '../shared/web_worker_test_util'; @@ -64,9 +64,11 @@ export function main() { // set up the ui side var uiMessageBrokerFactory = new ServiceMessageBrokerFactory(uiMessageBus, uiSerializer); var renderCompiler = new MessageBasedRenderCompiler(uiMessageBrokerFactory, tb.compiler); + renderCompiler.start(); var renderer = new MessageBasedRenderer(uiMessageBrokerFactory, uiMessageBus, uiSerializer, uiRenderViewStore, tb.renderer); - new WebWorkerMain(renderCompiler, renderer, null, null); + renderer.start(); + new WebWorkerApplication(null, null); return webWorkerBrokerFactory; } diff --git a/modules/angular2/test/web_workers/worker/xhr_impl_spec.ts b/modules/angular2/test/web_workers/worker/xhr_impl_spec.ts index e5e2464698..cfcbf47812 100644 --- a/modules/angular2/test/web_workers/worker/xhr_impl_spec.ts +++ b/modules/angular2/test/web_workers/worker/xhr_impl_spec.ts @@ -26,7 +26,7 @@ export function main() { const RESPONSE = "Example response text"; var messageBroker: any = new SpyMessageBroker(); - messageBroker.spy("runOnUiThread") + messageBroker.spy("runOnService") .andCallFake((args: UiArguments, returnType: Type) => { expect(args.method).toEqual("get"); expect(args.args.length).toEqual(1); diff --git a/modules/angular2/web_worker/ui.ts b/modules/angular2/web_worker/ui.ts index 94b2d3dd11..3cb30cd1bd 100644 --- a/modules/angular2/web_worker/ui.ts +++ b/modules/angular2/web_worker/ui.ts @@ -1 +1,4 @@ export * from "../src/web_workers/ui/application"; +export * from "../src/web_workers/shared/client_message_broker"; +export * from "../src/web_workers/shared/service_message_broker"; +export * from "../src/web_workers/shared/serializer"; diff --git a/modules/angular2/web_worker/worker.ts b/modules/angular2/web_worker/worker.ts index cfc4c552de..76dfebf4c8 100644 --- a/modules/angular2/web_worker/worker.ts +++ b/modules/angular2/web_worker/worker.ts @@ -7,3 +7,6 @@ export * from '../forms'; export * from '../render'; export * from '../profile'; export * from '../src/web_workers/worker/application'; +export * from "../src/web_workers/shared/client_message_broker"; +export * from "../src/web_workers/shared/service_message_broker"; +export * from "../src/web_workers/shared/serializer"; diff --git a/modules/examples/e2e_test/message_broker/message_broker_spec.ts b/modules/examples/e2e_test/message_broker/message_broker_spec.ts deleted file mode 100644 index 331ad3dc13..0000000000 --- a/modules/examples/e2e_test/message_broker/message_broker_spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {verifyNoBrowserErrors} from 'angular2/src/test_lib/e2e_util'; -import {PromiseWrapper} from "angular2/src/core/facade/async"; - -var URL = 'examples/src/message_broker/index.html'; - -describe('message bus', function() { - - afterEach(verifyNoBrowserErrors); - - it('should receive a response from the worker', function() { - browser.get(URL); - browser.sleep(5000); - - var VALUE = "hi there"; - var input = element.all(by.css("#echo_input")).first(); - input.sendKeys(VALUE); - clickComponentButton("body", "#send_echo"); - browser.wait(protractor.until.elementLocated(protractor.By.css("#echo_result .response")), - 5000); - expect(getComponentText("#echo_result", ".response")).toEqual(VALUE); - }); -}); - -describe('message broker', function() { - afterEach(verifyNoBrowserErrors); - - - it('should be able to run tasks on the UI thread after init', () => { - var VALUE = '5'; - - browser.get(URL); - browser.wait(protractor.until.elementLocated(protractor.By.css("#ui_result .result")), 5000); - expect(getComponentText("#ui_result", ".result")).toEqual(VALUE); - }); -}); - -function getComponentText(selector, innerSelector) { - return browser.executeScript('return document.querySelector("' + selector + '").querySelector("' + - innerSelector + '").textContent'); -} - -function clickComponentButton(selector, innerSelector) { - return browser.executeScript('return document.querySelector("' + selector + '").querySelector("' + - innerSelector + '").click()'); -} diff --git a/modules/examples/e2e_test/message_broker/message_broker_spec.dart b/modules/examples/e2e_test/web_workers/message_broker/message_broker_spec.dart similarity index 100% rename from modules/examples/e2e_test/message_broker/message_broker_spec.dart rename to modules/examples/e2e_test/web_workers/message_broker/message_broker_spec.dart diff --git a/modules/examples/e2e_test/web_workers/message_broker/message_broker_spec.ts b/modules/examples/e2e_test/web_workers/message_broker/message_broker_spec.ts new file mode 100644 index 0000000000..643eeccba8 --- /dev/null +++ b/modules/examples/e2e_test/web_workers/message_broker/message_broker_spec.ts @@ -0,0 +1,32 @@ +import {verifyNoBrowserErrors} from "angular2/src/test_lib/e2e_util"; +import {PromiseWrapper} from "angular2/src/core/facade/async"; + +var URL = "examples/src/web_workers/message_broker/index.html"; + +describe("MessageBroker", function() { + + afterEach(verifyNoBrowserErrors); + + it("should bootstrap", () => { + browser.get(URL); + waitForBootstrap(); + expect(element(by.css("app h1")).getText()).toEqual("WebWorker MessageBroker Test"); + }); + + it("should echo messages", () => { + const VALUE = "Hi There"; + browser.get(URL); + waitForBootstrap(); + + var input = element.all(by.css("#echo_input")).first(); + input.sendKeys(VALUE); + element(by.css("#send_echo")).click(); + var area = element(by.css("#echo_result")); + browser.wait(protractor.until.elementTextIs(area, VALUE), 5000); + expect(area.getText()).toEqual(VALUE); + }); +}); + +function waitForBootstrap(): void { + browser.wait(protractor.until.elementLocated(by.css("app h1")), 5000); +} diff --git a/modules/examples/src/message_broker/background_index.dart b/modules/examples/src/message_broker/background_index.dart deleted file mode 100644 index e3871fd701..0000000000 --- a/modules/examples/src/message_broker/background_index.dart +++ /dev/null @@ -1,29 +0,0 @@ -library angular2.examples.message_broker.background_index; - -import "package:angular2/src/web_workers/shared/client_message_broker.dart" - show ClientMessageBroker, UiArguments; -import "package:angular2/src/web_workers/shared/serializer.dart" - show Serializer; -import "package:angular2/src/web_workers/shared/isolate_message_bus.dart"; -import "package:angular2/src/web_workers/worker/application.dart" - show WebWorkerMessageBusSink; -import "package:angular2/src/core/facade/async.dart"; -import "dart:isolate"; - -main(List args, SendPort replyTo) { - ReceivePort rPort = new ReceivePort(); - var sink = new WebWorkerMessageBusSink(replyTo, rPort); - var source = new IsolateMessageBusSource(rPort); - IsolateMessageBus bus = new IsolateMessageBus(sink, source); - - ObservableWrapper.subscribe(bus.from("echo"), (value) { - ObservableWrapper.callNext(bus.to("echo"), value); - }); - - ClientMessageBroker broker = - new ClientMessageBroker(bus, new Serializer(null, null, null), "test"); - var args = new UiArguments("tester"); - broker.runOnUiThread(args, String).then((data) { - ObservableWrapper.callNext(bus.to("result"), data); - }); -} diff --git a/modules/examples/src/message_broker/background_index.ts b/modules/examples/src/message_broker/background_index.ts deleted file mode 100644 index 77442449d8..0000000000 --- a/modules/examples/src/message_broker/background_index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - PostMessageBus, - PostMessageBusSink, - PostMessageBusSource -} from 'angular2/src/web_workers/shared/post_message_bus'; -import {ObservableWrapper} from 'angular2/src/core/facade/async'; -import { - ClientMessageBroker, - UiArguments -} from "angular2/src/web_workers/shared/client_message_broker"; -import {Serializer} from "angular2/src/web_workers/shared/serializer"; - -interface PostMessageInterface { - (message: any, transferrables?:[ArrayBuffer]): void; -} -var _postMessage: PostMessageInterface = postMessage; - -export function main() { - var sink = new PostMessageBusSink({ - postMessage: - (message: any, transferrables?:[ArrayBuffer]) => { _postMessage(message, transferrables); } - }); - var source = new PostMessageBusSource(); - var bus = new PostMessageBus(sink, source); - - ObservableWrapper.subscribe(bus.from("echo"), - (value) => { ObservableWrapper.callNext(bus.to("echo"), value); }); - - var broker = new ClientMessageBroker(bus, new Serializer(null, null, null), "test"); - var args = new UiArguments("tester"); - broker.runOnUiThread(args, String) - .then((data: string) => { ObservableWrapper.callNext(bus.to("result"), data); }); -} diff --git a/modules/examples/src/message_broker/index.dart b/modules/examples/src/message_broker/index.dart deleted file mode 100644 index 8ea97d2f75..0000000000 --- a/modules/examples/src/message_broker/index.dart +++ /dev/null @@ -1,30 +0,0 @@ -library angular2.examples.message_broker.index; - -import "package:angular2/src/web_workers/ui/application.dart" - show spawnWebWorker; -import "package:angular2/src/core/facade/async.dart"; -import "dart:html"; - -main() { - var VALUE = 5; - spawnWebWorker(Uri.parse("background_index.dart")).then((bus) { - querySelector("#send_echo").addEventListener("click", (e) { - var val = (querySelector("#echo_input") as InputElement).value; - ObservableWrapper.callNext(bus.to("echo"), val); - }); - - ObservableWrapper.subscribe(bus.from("echo"), (message) { - querySelector("#echo_result") - .appendHtml("${message}"); - }); - ObservableWrapper.subscribe(bus.from("result"), (message) { - querySelector("#ui_result") - .appendHtml("${message}"); - }); - ObservableWrapper.subscribe(bus.from("test"), - (Map message) { - ObservableWrapper.callNext(bus.to("test"), - {'id': message['id'], 'type': "result", 'value': VALUE}); - }); - }); -} diff --git a/modules/examples/src/message_broker/index.ts b/modules/examples/src/message_broker/index.ts deleted file mode 100644 index 07ba361c67..0000000000 --- a/modules/examples/src/message_broker/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - PostMessageBus, - PostMessageBusSink, - PostMessageBusSource -} from 'angular2/src/web_workers/shared/post_message_bus'; -import {ObservableWrapper} from 'angular2/src/core/facade/async'; - -var webWorker = new Worker("loader.js"); -var sink = new PostMessageBusSink(webWorker); -var source = new PostMessageBusSource(webWorker); -var bus = new PostMessageBus(sink, source); -const VALUE = 5; - -document.getElementById("send_echo") - .addEventListener("click", (e) => { - var val = (document.getElementById("echo_input")).value; - ObservableWrapper.callNext(bus.to("echo"), val); - }); - -ObservableWrapper.subscribe(bus.from("echo"), (message) => { - document.getElementById("echo_result").innerHTML = `${message}`; -}); -ObservableWrapper.subscribe(bus.from("result"), (message) => { - document.getElementById("ui_result").innerHTML = `${message}`; -}); -ObservableWrapper.subscribe(bus.from("test"), (message: StringMap) => { - ObservableWrapper.callNext(bus.to("test"), {id: message['id'], type: "result", value: VALUE}); -}); diff --git a/modules/examples/src/message_broker/loader.js b/modules/examples/src/message_broker/loader.js deleted file mode 100644 index 0c41c9a0d7..0000000000 --- a/modules/examples/src/message_broker/loader.js +++ /dev/null @@ -1,38 +0,0 @@ -$SCRIPTS$ - -//importScripts("math_worker.js").execute(); -//System.import("examples/src/web_workers/math_worker").then(function(m){console.log("got", m)}); -//importScripts("rx.js"); - -// TODO: do this correctly with lang facade -window = { - setTimeout: setTimeout, - Map: Map, - Set: Set, - Array: Array, - Reflect: Reflect, - RegExp: RegExp, - Promise: Promise, - Date: Date -}; -assert = function(){}; - - -System.config({ - baseURL: '/', - defaultJSExtensions: true, - paths: { - 'rx': 'examples/src/message_broker/rx.js' - } -}); - -System.import("examples/src/message_broker/background_index").then(function(m){ - console.log("running main"); - try{ - m.main(); - } catch (e){ - console.error(e); - } -}, function(error){ - console.error("error loading background", error); -}); diff --git a/modules/examples/src/web_workers/message_broker/background_index.dart b/modules/examples/src/web_workers/message_broker/background_index.dart new file mode 100644 index 0000000000..5611144797 --- /dev/null +++ b/modules/examples/src/web_workers/message_broker/background_index.dart @@ -0,0 +1,12 @@ +library angular2.examples.message_broker.background_index; + +import "package:angular2/web_worker/worker.dart"; +import "package:angular2/src/core/reflection/reflection_capabilities.dart"; +import "package:angular2/src/core/reflection/reflection.dart"; +import "index_common.dart" show App; +import "dart:isolate"; + +main(List args, SendPort replyTo) { + reflector.reflectionCapabilities = new ReflectionCapabilities(); + bootstrapWebWorker(replyTo, App).catchError((error) => throw error); +} diff --git a/modules/examples/src/web_workers/message_broker/background_index.ts b/modules/examples/src/web_workers/message_broker/background_index.ts new file mode 100644 index 0000000000..39f7b0935b --- /dev/null +++ b/modules/examples/src/web_workers/message_broker/background_index.ts @@ -0,0 +1,6 @@ +import {bootstrapWebWorker} from "angular2/web_worker/worker"; +import {App} from "./index_common"; + +export function main() { + bootstrapWebWorker(App); +} diff --git a/modules/examples/src/web_workers/message_broker/index.dart b/modules/examples/src/web_workers/message_broker/index.dart new file mode 100644 index 0000000000..4207b4364e --- /dev/null +++ b/modules/examples/src/web_workers/message_broker/index.dart @@ -0,0 +1,22 @@ +library angular2.examples.message_broker.index; + +import "package:angular2/web_worker/ui.dart"; +import "package:angular2/src/core/reflection/reflection_capabilities.dart"; +import "package:angular2/src/core/reflection/reflection.dart"; +import "dart:html"; + +main() { + reflector.reflectionCapabilities = new ReflectionCapabilities(); + const ECHO_CHANNEL = "ECHO"; + bootstrap("background_index.dart").then((instance) { + var broker = instance.app.createClientMessageBroker(ECHO_CHANNEL); + querySelector("#send_echo").addEventListener("click", (e) { + var val = (querySelector("#echo_input") as InputElement).value; + var args = new UiArguments("echo", [new FnArg(val, PRIMITIVE)]); + broker.runOnService(args, PRIMITIVE).then((echo_result) { + querySelector("#echo_result") + .appendHtml("${echo_result}"); + }); + }); + }); +} diff --git a/modules/examples/src/message_broker/index.html b/modules/examples/src/web_workers/message_broker/index.html similarity index 94% rename from modules/examples/src/message_broker/index.html rename to modules/examples/src/web_workers/message_broker/index.html index aea5bc922f..dd783c3968 100644 --- a/modules/examples/src/message_broker/index.html +++ b/modules/examples/src/web_workers/message_broker/index.html @@ -2,6 +2,7 @@ Message Broker Example +

diff --git a/modules/examples/src/web_workers/message_broker/index.ts b/modules/examples/src/web_workers/message_broker/index.ts new file mode 100644 index 0000000000..5b9b4541a2 --- /dev/null +++ b/modules/examples/src/web_workers/message_broker/index.ts @@ -0,0 +1,25 @@ +import {bootstrap, UiArguments, FnArg, PRIMITIVE} from "angular2/web_worker/ui"; + +const ECHO_CHANNEL = "ECHO"; + +var instance = bootstrap("loader.js"); +var broker = instance.app.createClientMessageBroker(ECHO_CHANNEL); + +document.getElementById("send_echo") + .addEventListener("click", (e) => { + var val = (document.getElementById("echo_input")).value; + // TODO(jteplitz602): Replace default constructors with real constructors + // once they're in the .d.ts file (#3926) + var args = new UiArguments(); + args.method = "echo"; + var fnArg = new FnArg(); + fnArg.value = val; + fnArg.type = PRIMITIVE; + args.args = [fnArg]; + + broker.runOnService(args, PRIMITIVE) + .then((echo_result: string) => { + document.getElementById("echo_result").innerHTML = + `${echo_result}`; + }); + }); diff --git a/modules/examples/src/web_workers/message_broker/index_common.ts b/modules/examples/src/web_workers/message_broker/index_common.ts new file mode 100644 index 0000000000..c2fc51ee42 --- /dev/null +++ b/modules/examples/src/web_workers/message_broker/index_common.ts @@ -0,0 +1,17 @@ +import {PromiseWrapper} from "angular2/src/core/facade/async"; +import {Component, View, ServiceMessageBrokerFactory, PRIMITIVE} from "angular2/web_worker/worker"; + +const ECHO_CHANNEL = "ECHO"; + +@Component({selector: 'app', viewBindings: [ServiceMessageBrokerFactory]}) +@View({template: "

WebWorker MessageBroker Test

"}) +export class App { + constructor(private _serviceBrokerFactory: ServiceMessageBrokerFactory) { + var broker = _serviceBrokerFactory.createMessageBroker(ECHO_CHANNEL); + broker.registerMethod("echo", [PRIMITIVE], this._echo, PRIMITIVE); + } + + private _echo(val: string) { + return PromiseWrapper.wrap(() => { return val; }); + } +} diff --git a/modules/examples/src/web_workers/message_broker/loader.js b/modules/examples/src/web_workers/message_broker/loader.js new file mode 100644 index 0000000000..e86c1ba527 --- /dev/null +++ b/modules/examples/src/web_workers/message_broker/loader.js @@ -0,0 +1,19 @@ +$SCRIPTS$ + + System.config({ + baseURL: '/', + defaultJSExtensions: true, + paths: {'rx': 'examples/src/web_workers/message_broker/rx.js'} + }); + +System.import("examples/src/web_workers/message_broker/background_index") + .then( + function(m) { + console.log("running main"); + try { + m.main(); + } catch (e) { + console.error(e); + } + }, + function(error) { console.error("error loading background", error); }); diff --git a/tools/broccoli/trees/browser_tree.ts b/tools/broccoli/trees/browser_tree.ts index a0929c6bfa..ecb3214948 100644 --- a/tools/broccoli/trees/browser_tree.ts +++ b/tools/broccoli/trees/browser_tree.ts @@ -63,10 +63,10 @@ const kServedPaths = [ 'examples/src/material/progress-linear', 'examples/src/material/radio', 'examples/src/material/switcher', - 'examples/src/message_broker', 'examples/src/web_workers/kitchen_sink', 'examples/src/web_workers/todo', - 'examples/src/web_workers/images' + 'examples/src/web_workers/images', + 'examples/src/web_workers/message_broker' ];