refactor(WebWorker): Use the new generic bootstrap.

BREAKING CHANGE:

You can no longer bootstrap a WebWorker or Isolate using `bootstrap` or `bootstrapWebWorker`. Instead you have to do the following:

In TypeScript:
```TypeScript
// index.js
import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT} from "angular2/platforms/worker_render";
import {platform} from "angular2/platform";

platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"});
```
```JavaScript
// loader.js
importScripts("https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.js", "https://jspm.io/system@0.16.js", "angular2/web_worker/worker.js");
System.import("app");
```
```TypeScript
// app.ts
import {Component, View} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platforms/worker_app";
import {platform} from "angular2/platform";

@Component({
  selector: "hello-world"
})
@View({
  template: "<h1>Hello {{name}}</h1>
})
export class HelloWorld {
  name: string = "Jane";
}

platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker, optionalProviders?)
.then((ref) => ref.bootstrap(RootComponent));
```

In Dart:
```Dart
// index.dart
import "angular2/platform.dart";
import "angular2/platforms/worker_render.dart";

main() {
  platform([WORKER_RENDER_PLATFORM])
  .asyncApplication(initIsolate("my_worker.dart"));
}
```
```Dart
// background_index.dart
import "angular2/platform.dart";
import "angular2/platforms/worker_app.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";

@Component(
  selector: "hello-world"
)
@View(
  template: "<h1>Hello {{name}}</h1>"
)
class HelloWorld {
  String name = "Jane";
}

main(List<String> args, SendPort replyTo) {
  reflector.reflectionCapabilities = new ReflectionCapabilities();
  platform([WORKER_APP_PLATFORM])
    .asyncApplication(setupIsolate(replyTo))
      .then((ref) => ref.bootstrap(RootComponent));
}

```

You should no longer import from the `angular2/web_worker/worker` and `angular2/web_worker/ui` paths. Instead you can now import directly from core, directives, etc..

The WebWorkerApplication class has been removed. If you want to use ServiceMessageBroker or ClientMessageBroker on the render thread, you must inject their factories via DI.
If you need to use the MessageBus on the render thread you must also obtain it through DI.

closes #3277
closes #5473

Closes #5519
This commit is contained in:
Jason Teplitz 2015-12-02 20:25:24 -08:00
parent 93a1ec29e1
commit 1710272b3c
48 changed files with 827 additions and 719 deletions

View File

@ -19,8 +19,10 @@ better framerate and UX for applications.
## Bootstrapping a WebWorker Application
Bootstrapping a WebWorker application is not much different than bootstrapping a normal application.
The primary difference is that you don't pass your root component directly to ```bootstrap```.
Instead you pass the name of a background script that calls ```bootstrapWebWorker``` with your root component.
The main difference is that you need to do the bootstrap process on both the worker and render thread.
Unlike in a standard Angular2 application you don't bootstrap your main component on the render thread.
Instead you initialize a new application injector with the WORKER_APP_PLATFORM providers and provide the name
of your WebWorker script. See the example below for details:
### Example
To bootstrap Hello World in a WebWorker we do the following in TypeScript
@ -39,8 +41,11 @@ To bootstrap Hello World in a WebWorker we do the following in TypeScript
```
```TypeScript
// index.js
import {bootstrap} from "angular2/web_worker/ui";
bootstrap("loader.js");
import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT} from "angular2/platform/worker_render";
import {platform} from "angular2/core";
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"});
```
```JavaScript
// loader.js
@ -49,7 +54,9 @@ System.import("app");
```
```TypeScript
// app.ts
import {Component, View, bootstrapWebWorker} from "angular2/web_worker/worker";
import {Component, View, platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app";
@Component({
selector: "hello-world"
})
@ -60,21 +67,19 @@ export class HelloWorld {
name: string = "Jane";
}
bootstrapWebWorker(HelloWorld);
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker, optionalProviders?)
.then((ref) => ref.bootstrap(RootComponent));
```
There's a few important things to note here:
* On the UI side we import all angular types from `angular2/web_worker/ui` and on the worker side we import from
`angular2/web_worker/worker`. These modules include all the typings in the WebWorker bundle. By importing from
these URLs instead of `angular2/angular2` we can statically ensure that our app does not reference a type that
doesn't exist in the context it's mean to execute in. For example, if we tried to import DomRenderer in the Worker
or NgFor on the UI we would get a compiler error.
* The UI loads angular from the file `angular2/web_worker/ui.js` and the Worker loads angular from
`angular2/web_worker/worker.js`. These bundles are created specifically for using WebWorkers and should be used
instead of the normal angular2.js file. Both files contain subsets of the angular2 codebase that is designed to
run specifically on the UI or Worker. Additionally, they contain the core messaging infrastructure used to
communicate between the Worker and the UI. This messaging code is not in the standard angular2.js file.
* We pass `loader.js` to bootstrap and not `app.ts`. You can think of `loader.js` as the `index.html` of the
Worker. Since WebWorkers share no memory with the UI we need to reload the angular2 dependencies before
* We pass `loader.js` to our application injector using the WORKER_SCRIPT symbol. This tells angular that our WebWorkers's init script is located at `loader.js`.
You can think of `loader.js` as the index.html file for the WebWorker.
Since WebWorkers share no memory with the UI we need to reload the angular2 dependencies before
bootstrapping our application. We do this with `importScripts`. Additionally, we need to do this in a different
file than `app.ts` because our module loader (System.js in this example) has not been loaded yet, and `app.ts`
will be compiled with a `System.define` call at the top.
@ -93,17 +98,18 @@ For reference, here's the same HelloWorld example in Dart.
```
```Dart
// index.dart
import "package:angular2/web_worker/ui.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "angular2/core.dart";
import "angular2/platform/worker_render.dart";
main() {
reflector.reflectionCapabilities = new ReflectionCabilities();
bootstrap("app.dart");
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("my_worker.dart"));
}
```
```Dart
import "package:angular2/web_worker/worker.dart";
// background_index.dart
import "angular2/core.dart";
import "angular2/platform/worker_app.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
@ -119,14 +125,16 @@ class HelloWorld {
main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrapWebWorker(replyTo, HelloWorld);
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupIsolate(replyTo))
.then((ref) => ref.bootstrap(RootComponent));
}
```
This code is nearly the same as the TypeScript version with just a couple key differences:
* We don't have a `loader.js` file. Dart applications don't need this file because you don't need a module loader.
* We pass a `SendPort` to `bootstrapWebWorker`. Dart applications use the Isolate API, which communicates via
Dart's Port abstraction. When you call `bootstrap` from the UI thread, angular starts a new Isolate to run
Dart's Port abstraction. When you call `setupIsolate` from the UI thread, angular starts a new Isolate to run
your application logic. When Dart starts a new Isolate it passes a `SendPort` to that Isolate so that it
can communicate with the Isolate that spawned it. You need to pass this `SendPort` to `bootstrapWebWorker`
so that Angular can communicate with the UI.
@ -136,6 +144,8 @@ but should use the angular 2 transformer to remove it in your final JS code. Not
with running the transformer on your UI code (#3971). You can (and should) pass the file where you call
`bootstrapWebWorker` as an entry point to the transformer, but you should not pass your UI index file
to the transformer until that bug is fixed.
* In dart we call `asyncApplication` instead of `application` because starting an isolate in Dart is asyncronous
whereas starting a new WebWorker in JavaScript is a synchronous operation.
## Writing WebWorker Compatible Components
You can do almost everything in a WebWorker component that you can do in a typical Angular 2 Component.
@ -202,17 +212,22 @@ can make it easy to catch tricky browser compatibility issues.
[MessageBroker](#using-the-messagebroker-in-your-application). However, if you want to control the messaging
protocol yourself you can use the MessageBus directly.
You can obtain the MessageBus on both the render and worker thread through DI.
To use the MessageBus you need to initialize a new channel on both the UI and WebWorker.
In TypeScript that would look like this:
```TypeScript
// index.ts, which is running on the UI.
var instance = bootstrap("loader.js");
var bus = instance.bus;
import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT, MessageBus} from "angular2/platform/worker_render";
import {platform} from "angular2/core";
let appRef = platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"});
let bus = appRef.injector.get(MessageBus);
bus.initChannel("My Custom Channel");
```
```TypeScript
// background_index.ts, which is running on the WebWorker
import {MessageBus} from 'angular2/web_worker/worker';
import {MessageBus} from 'angular2/platform/worker_app';
@Component({...})
@View({...})
export class MyComponent {
@ -226,15 +241,19 @@ Once the channel has been initialized either side can use the `from` and `to` me
and receive messages. Both methods return EventEmitter. Expanding on the example from earlier:
```TypeScript
// index.ts, which is running on the UI.
import {bootstrap} from 'angular2/web_worker/ui';
var instance = bootstrap("loader.js");
var bus = instance.bus;
import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT, MessageBus} from "angular2/platform/worker_render";
import {platform} from "angular2/core";
let appRef = platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"});
let bus = appRef.injector.get(MessageBus);
bus.initChannel("My Custom Channel");
bus.to("My Custom Channel").emit("hello from the UI");
bus.to("My Custom Channel").emit("Hello from the UI");
```
```TypeScript
// background_index.ts, which is running on the WebWorker
import {MessageBus, Component, View} from 'angular2/web_worker/worker';
import {Component, View} from 'angular2/core';
import {MessageBus} from 'angular2/platform/worker_app';
@Component({...})
@View({...})
export class MyComponent {
@ -253,16 +272,21 @@ This example is nearly identical in Dart, and is included below for reference:
import 'package:angular2/web_workers/ui.dart';
main() {
var instance = bootstrap("background_index.dart");
var bus = instance.bus;
bus.initChannel("My Custom Channel");
bus.to("My Custom Channel").add("hello from the UI");
import "angular2/core.dart";
import "angular2/platform/worker_render.dart";
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("my_worker.dart")).then((ref) {
var bus = ref.injector.get(MessageBus);
bus.initChannel("My Custom Channel");
bus.to("My Custom Channel").add("hello from the UI");
});
}
```
```Dart
// background_index.dart, which is running on the WebWorker
import 'package:angular2/web_worker/worker.dart';
import 'package:angular2/platform/worker_app.dart';
@Component(...)
@View(...)
class MyComponent {
@ -298,7 +322,7 @@ change detection. Generally, you want your channels to run inside the zone unles
they need to run outside the zone.
### Implementing and Using a Custom MessageBus
**Note:** Implementing and using a Custom MessageBus is experimental and requires importing from private APIs.
**Note:** Implementing and using a Custom MessageBus is experimental and the APIs may change.
If you want to drive your application from something other than a WebWorker you can implement a custom message
bus. Implementing a custom message bus just means creating a class that fulfills the API specified by the
@ -338,54 +362,97 @@ class JsonMessageBusSource extends GenericMessageBuSource {
}
```
Once you've implemented your custom MessageBus in either TypeScript or Dart, you can tell angular to use it like
so:
Once you've implemented your custom MessageBus in either TypeScript or Dart, you must provide it through DI
during bootstrap like so:
In TypeScript:
```TypeScript
// index.ts, running on the UI side
import {bootstrapUICommon} from 'angular2/src/web_workers/ui/impl';
import {platform, Provider, APP_INITIALIZER, Injector} from 'angular2/core';
import {
WORKER_RENDER_PLATFORM,
WORKER_RENDER_APP_COMMON,
initializeGenericWorkerRenderer,
MessageBus
} from 'angular2/platform/worker_render';
var bus = new MyAwesomeMessageBus();
bootstrapUICommon(bus);
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APP_COMMON, new Provider(MessageBus, {useValue: bus}),
new Provider(APP_INITIALIZER, {
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
deps: [Injector],
multi: true
})
]);
```
```TypeScript
// background_index.ts, running on the application side
import {bootstrapWebWorkerCommon} from 'angular2/src/web_workers/worker/application_common';
import {WORKER_APP_PLATFORM, genericWorkerAppProviders} from "angular2/platform/worker_app";
import {NgZone, platform, Provider} from "angular/core";
import {MyApp} from './app';
var bus = new MyAwesomeMessageBus();
bootstrapWebWorkerCommon(MyApp, bus);
platform([WORKER_APP_PLATFORM_PROVIDERS])
.asyncApplication(initAppThread, optionalProviders?)
.then((ref) => ref.bootstrap(MyApp));
function initAppThread(zone: NgZone): Promise<Array<Type | Provider | any[]>> {
/**
* Do initializtion work here to set up the app thread and MessageBus
* Once you have a working MessageBus that communicates with the render thread you should call genericWorkerAppProviders
* to get a list of Providers.
*/
var bus = new MyAwesomeMessageBus();
return genericWorkerAppProviders(myBus, zone);
}
```
In Dart:
```Dart
// index.dart, running on the UI side
import 'package:angular2/src/web_workers/ui/impl.dart' show bootstrapUICommon;
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import 'package:angular2/core.dart';
import 'package:angular2/platform/worker_render.dart';
main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
var bus = new MyAwesomeMessageBus();
bootstrapUiCommon(bus);
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APP_COMMON, new Provider(MessageBus, useValue: bus),
new Provider(APP_INITIALIZER,
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
deps: [Injector],
multi: true
)
]);
}
```
```Dart
// background_index.dart, running on the application side
import "package:angular2/src/web_workers/worker/application_common.dart" show bootstrapWebWorkerCommon;
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/platform/worker_app.dart";
import "package:angular2/core.dart";
import "./app.dart" show MyApp;
main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
var bus = new MyAwesomeMessageBus();
bootstrapWebWorkerCommon(MyApp, bus);
reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM_PROVIDERS])
.asyncApplication(initAppThread, optionalProviders?)
.then((ref) => ref.bootstrap(MyApp));
}
Future<dynamic> initAppThread(NgZone zone) {
var bus = new MyAwesomeMessageBus();
return genericWorkerAppProviders(myBus, zone);
}
```
Notice how we call `bootstrapUICommon` instead of `bootstrap` from the UI side. `bootstrap` spans a new WebWorker
/ Isolate and attaches the default angular MessageBus to it. If you're using a custom MessageBus you are
responsible for setting up the application side and initiating communication with it. `bootstrapUICommon` assumes
that the given MessageBus is already set up and can communicate with the application.
Similarly, we call `bootstrapWebWorkerCommon` instead of `boostrapWebWorker` from the application side. This is
because `bootstrapWebWorker` assumes you're using the default angular MessageBus and initializes a new one for you.
Notice how we use the `WORKER_RENDER_APP_COMMON` providers instead of the `WORKER_RENDER_APP` providers on the render thread.
This is because the `WORKER_RENDER_APP` providers include an application initializer that starts a new WebWorker/Isolate.
The `WORKER_RENDER_APP_COMMON` providers make no assumption about where your application code lives.
However, we now need to provide our own app initializer. At the very least this initializer needs to call `initializeGenericWorkerRenderer`.
This function performs necessary setup work to bootstrap the application.
Similarly we don&amp;t call `setupWebWorker` or `setupIsolate` from the application thread.
Instead we have our own initilization method that sets up our MessageBus and calls `genericWorkerAppProviders`
to finish setting up the application injector.
## MessageBroker
The MessageBroker is a higher level messaging abstraction that sits on top of the MessageBus. It is used when you
@ -407,18 +474,21 @@ MessageBrokers in an application. For a more complete example, check out the `We
#### Using the MessageBroker in TypeScript
```TypeScript
// index.ts, which is running on the UI with a method that we want to expose to a WebWorker
import {bootstrap} from 'angular2/web_worker/ui';
import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT, ServiceMessageBrokerFactory} from "angular2/platform/worker_render";
import {platform} from "angular2/core";
var instance = bootstrap("loader.js");
var broker = instance.app.createServiceMessageBroker("My Broker Channel");
let appRef = platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"});
let injector = instance.injector;
var broker = injector.get(ServiceMessageBrokerFactory).createMessageBroker("My Broker Channel");
// assume we have some function doCoolThings that takes a string argument and returns a Promise<string>
broker.registerMethod("awesomeMethod", [PRIMITIVE], (arg1: string) => doCoolThing(arg1), PRIMITIVE);
```
```TypeScript
// background.ts, which is running on a WebWorker and wants to execute a method on the UI
import {Component, View, ClientMessageBrokerFactory, PRIMITIVE, UiArguments, FnArgs}
from 'angular2/web_worker/worker';
import {Component, View} from 'angular2/core';
import {ClientMessageBrokerFactory, PRIMITIVE, UiArguments, FnArgs} from 'angular2/platform/worker_app';
@Component(...)
@View(...)
@ -437,20 +507,24 @@ export class MyComponent {
#### Using the MessageBroker in Dart
```Dart
// index.dart, which is running on the UI with a method that we want to expose to a WebWorker
import 'package:angular2/web_worker/ui.dart';
import "angular2/core.dart";
import "angular2/platform/worker_render.dart";
main() {
var instance = bootstrap("background.dart");
var broker = instance.app.createServiceMessageBroker("My Broker Channel");
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("my_worker.dart")).then((ref) {
var broker = ref.injector.get(ServiceMessageBrokerFactory).createMessageBroker("My Broker Channel");
// assume we have some function doCoolThings that takes a String argument and returns a Future<String>
broker.registerMethod("awesomeMethod", [PRIMITIVE], (String arg1) => doCoolThing(arg1), PRIMITIVE);
// assume we have some function doCoolThings that takes a String argument and returns a Future<String>
broker.registerMethod("awesomeMethod", [PRIMITIVE], (String arg1) => doCoolThing(arg1), PRIMITIVE);
});
}
```
```Dart
// background.dart, which is running on a WebWorker and wants to execute a method on the UI
import 'package:angular2/web_worker/worker.dart';
import 'package:angular2/core.dart';
import 'package:angular2/platform/worker_app.dart';
@Component(...)
@View(...)

View File

@ -0,0 +1,18 @@
export {
WORKER_APP_PLATFORM,
genericWorkerAppProviders
} from 'angular2/src/platform/worker_app_common';
export * from 'angular2/src/platform/worker_app';
export {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from '../src/web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from '../src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
export * from '../src/web_workers/shared/message_bus';

View File

@ -0,0 +1,20 @@
library angular2.platform.worker_render;
export 'package:angular2/src/platform/worker_render_common.dart'
show
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM,
WORKER_RENDER_APP_COMMON,
initializeGenericWorkerRenderer;
export 'package:angular2/src/platform/worker_render.dart'
show WORKER_RENDER_APP, initIsolate, WebWorkerInstance;
export '../src/web_workers/shared/client_message_broker.dart'
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
export '../src/web_workers/shared/service_message_broker.dart'
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;
export '../src/web_workers/shared/serializer.dart' show PRIMITIVE;
export '../src/web_workers/shared/message_bus.dart';

View File

@ -0,0 +1,20 @@
export {
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM,
initializeGenericWorkerRenderer,
WORKER_RENDER_APP_COMMON
} from 'angular2/src/platform/worker_render_common';
export * from 'angular2/src/platform/worker_render';
export {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from '../src/web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from '../src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
export * from '../src/web_workers/shared/message_bus';

View File

@ -191,8 +191,8 @@ export abstract class PlatformRef {
* new application. Once this promise resolves, the application will be
* constructed in the same manner as a normal `application()`.
*/
abstract asyncApplication(bindingFn: (zone: NgZone) =>
Promise<Array<Type | Provider | any[]>>): Promise<ApplicationRef>;
abstract asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>,
providers?: Array<Type | Provider | any[]>): Promise<ApplicationRef>;
/**
* Destroy the Angular platform and all Angular applications on the page.
@ -217,12 +217,15 @@ export class PlatformRef_ extends PlatformRef {
return app;
}
asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>):
Promise<ApplicationRef> {
asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>,
additionalProviders?: Array<Type | Provider | any[]>): Promise<ApplicationRef> {
var zone = createNgZone();
var completer = PromiseWrapper.completer();
zone.run(() => {
PromiseWrapper.then(bindingFn(zone), (providers: Array<Type | Provider | any[]>) => {
if (isPresent(additionalProviders)) {
providers = ListWrapper.concat(providers, additionalProviders);
}
completer.resolve(this._initApp(zone, providers));
});
});

View File

@ -79,4 +79,4 @@ export function initDomAdapter() {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
}

View File

@ -0,0 +1,25 @@
library angular2.src.platform.worker_app;
import 'package:angular2/src/core/zone/ng_zone.dart';
import 'package:angular2/src/platform/server/webworker_adapter.dart';
import 'package:angular2/src/platform/worker_app_common.dart';
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
import 'dart:isolate';
setupIsolate(SendPort replyTo) {
return (NgZone zone) {
WebWorkerDomAdapter.makeCurrent();
ReceivePort rPort = new ReceivePort();
var sink = new WebWorkerMessageBusSink(replyTo, rPort);
var source = new IsolateMessageBusSource(rPort);
IsolateMessageBus bus = new IsolateMessageBus(sink, source);
return genericWorkerAppProviders(bus, zone);
};
}
class WebWorkerMessageBusSink extends IsolateMessageBusSink {
WebWorkerMessageBusSink(SendPort sPort, ReceivePort rPort) : super(sPort) {
sPort.send(rPort.sendPort);
}
}

View File

@ -0,0 +1,28 @@
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang';
import {Provider} from 'angular2/src/core/di';
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from 'angular2/src/web_workers/shared/post_message_bus';
import {genericWorkerAppProviders} from './worker_app_common';
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
interface PostMessageInterface {
(message: any, transferrables?:[ArrayBuffer]): void;
}
var _postMessage: PostMessageInterface = <any>postMessage;
export function setupWebWorker(zone: NgZone): Promise<Array<Type | Provider | any[]>> {
Parse5DomAdapter.makeCurrent();
var sink = new PostMessageBusSink({
postMessage:
(message: any, transferrables?:[ArrayBuffer]) => { _postMessage(message, transferrables); }
});
var source = new PostMessageBusSource();
var bus = new PostMessageBus(sink, source);
return genericWorkerAppProviders(bus, zone);
}

View File

@ -0,0 +1,97 @@
import {XHR} from 'angular2/src/compiler/xhr';
import {WebWorkerXHRImpl} from 'angular2/src/web_workers/worker/xhr_impl';
import {ListWrapper} from 'angular2/src/facade/collection';
import {AppRootUrl} from 'angular2/src/compiler/app_root_url';
import {WebWorkerRenderer} from 'angular2/src/web_workers/worker/renderer';
import {print, Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {Renderer} from 'angular2/src/core/render/api';
import {
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ExceptionHandler,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
} from 'angular2/core';
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from "angular2/common";
import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/client_message_broker';
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/service_message_broker';
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
import {Serializer} from "angular2/src/web_workers/shared/serializer";
import {ON_WEB_WORKER} from "angular2/src/web_workers/shared/api";
import {Provider} from 'angular2/src/core/di';
import {RenderProtoViewRefStore} from 'angular2/src/web_workers/shared/render_proto_view_ref_store';
import {
RenderViewWithFragmentsStore
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
import {WebWorkerEventDispatcher} from 'angular2/src/web_workers/worker/event_dispatcher';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {Promise, PromiseWrapper, PromiseCompleter} from 'angular2/src/facade/async';
import {SETUP_CHANNEL} from 'angular2/src/web_workers/shared/messaging_api';
import {ObservableWrapper} from 'angular2/src/facade/async';
class PrintLogger {
log = print;
logError = print;
logGroup = print;
logGroupEnd() {}
}
export const WORKER_APP_PLATFORM: Array<any /*Type | Provider | any[]*/> =
CONST_EXPR([PLATFORM_COMMON_PROVIDERS]);
export const WORKER_APP_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
APPLICATION_COMMON_PROVIDERS,
COMPILER_PROVIDERS,
FORM_PROVIDERS,
Serializer,
new Provider(PLATFORM_PIPES, {useValue: COMMON_PIPES, multi: true}),
new Provider(PLATFORM_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}),
new Provider(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}),
new Provider(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}),
WebWorkerRenderer,
new Provider(Renderer, {useExisting: WebWorkerRenderer}),
new Provider(ON_WEB_WORKER, {useValue: true}),
RenderViewWithFragmentsStore,
RenderProtoViewRefStore,
new Provider(ExceptionHandler, {useFactory: _exceptionHandler, deps: []}),
WebWorkerXHRImpl,
new Provider(XHR, {useExisting: WebWorkerXHRImpl}),
WebWorkerEventDispatcher
]);
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(new PrintLogger());
}
/**
* Asynchronously returns a list of providers that can be used to initialize the
* Application injector.
* Also takes care of attaching the {@link MessageBus} to the given {@link NgZone}.
*/
export function genericWorkerAppProviders(bus: MessageBus,
zone: NgZone): Promise<Array<Type | Provider | any[]>> {
var bootstrapProcess: PromiseCompleter<any> = PromiseWrapper.completer();
bus.attachToZone(zone);
bus.initChannel(SETUP_CHANNEL, false);
var subscription: any;
var emitter = bus.from(SETUP_CHANNEL);
subscription = ObservableWrapper.subscribe(emitter, (initData: {[key: string]: any}) => {
var bindings = ListWrapper.concat(WORKER_APP_COMMON_PROVIDERS, [
new Provider(MessageBus, {useValue: bus}),
new Provider(AppRootUrl, {useValue: new AppRootUrl(initData['rootUrl'])}),
]);
bootstrapProcess.resolve(bindings);
ObservableWrapper.dispose(subscription);
});
ObservableWrapper.callNext(bus.to(SETUP_CHANNEL), "ready");
return bootstrapProcess.promise;
}

View File

@ -0,0 +1,68 @@
library angular2.src.platform.worker_render;
import 'package:angular2/src/platform/worker_render_common.dart'
show
WORKER_RENDER_APP_COMMON,
WORKER_RENDER_MESSAGING_PROVIDERS,
WORKER_SCRIPT,
initializeGenericWorkerRenderer;
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
import 'package:angular2/src/web_workers/shared/message_bus.dart';
import 'package:angular2/core.dart';
import 'package:angular2/src/core/di.dart';
import 'package:angular2/src/core/zone/ng_zone.dart';
import 'dart:isolate';
import 'dart:async';
const WORKER_RENDER_APP = WORKER_RENDER_APP_COMMON;
initIsolate(String scriptUri) {
return (NgZone zone) async {
var instance = await spawnIsolate(Uri.parse(scriptUri));
return [
WORKER_RENDER_APP_COMMON,
new Provider(WebWorkerInstance, useValue: instance),
new Provider(APP_INITIALIZER,
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
multi: true,
deps: [Injector]),
new Provider(MessageBus, useValue: instance.bus)
];
};
}
/**
* Spawns a new class and initializes the WebWorkerInstance
*/
Future<WebWorkerInstance> spawnIsolate(Uri uri) async {
var receivePort = new ReceivePort();
var isolateEndSendPort = receivePort.sendPort;
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 WebWorkerInstance(isolate, bus);
}
class UIMessageBusSource extends IsolateMessageBusSource {
UIMessageBusSource(ReceivePort port) : super(port);
Future<SendPort> get sink => stream.firstWhere((message) {
return message is SendPort;
});
}
/**
* Wrapper class that exposes the Isolate
* and underlying {@link MessageBus} for lower level message passing.
*/
@Injectable()
class WebWorkerInstance {
Isolate worker;
MessageBus bus;
WebWorkerInstance(this.worker, this.bus);
}

View File

@ -0,0 +1,77 @@
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from 'angular2/src/web_workers/shared/post_message_bus';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {APP_INITIALIZER} from 'angular2/core';
import {Injector, Injectable, Provider} from 'angular2/src/core/di';
import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup';
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
import {
WORKER_RENDER_APP_COMMON,
WORKER_RENDER_MESSAGING_PROVIDERS,
WORKER_SCRIPT,
initializeGenericWorkerRenderer
} from 'angular2/src/platform/worker_render_common';
import {BaseException} from 'angular2/src/facade/exceptions';
import {CONST_EXPR} from 'angular2/src/facade/lang';
/**
* Wrapper class that exposes the Worker
* and underlying {@link MessageBus} for lower level message passing.
*/
@Injectable()
export class WebWorkerInstance {
public worker: Worker;
public bus: MessageBus;
/** @internal */
public init(worker: Worker, bus: MessageBus) {
this.worker = worker;
this.bus = bus;
}
}
/**
* An array of providers that should be passed into `application()` when initializing a new Worker.
*/
export const WORKER_RENDER_APP: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
WORKER_RENDER_APP_COMMON,
WebWorkerInstance,
new Provider(APP_INITIALIZER,
{
useFactory: (injector) => () => initWebWorkerApplication(injector),
multi: true,
deps: [Injector]
}),
new Provider(MessageBus, {useFactory: (instance) => instance.bus, deps: [WebWorkerInstance]})
]);
function initWebWorkerApplication(injector: Injector): void {
var scriptUri: string;
try {
scriptUri = injector.get(WORKER_SCRIPT);
} catch (e) {
throw new BaseException(
"You must provide your WebWorker's initialization script with the WORKER_SCRIPT token");
}
let instance = injector.get(WebWorkerInstance);
spawnWebWorker(scriptUri, instance);
initializeGenericWorkerRenderer(injector);
}
/**
* Spawns a new class and initializes the WebWorkerInstance
*/
function spawnWebWorker(uri: string, instance: WebWorkerInstance): void {
var webWorker: Worker = new Worker(uri);
var sink = new PostMessageBusSink(webWorker);
var source = new PostMessageBusSource(webWorker);
var bus = new PostMessageBus(sink, source);
instance.init(webWorker, bus);
}

View File

@ -0,0 +1,120 @@
import {CONST_EXPR} from 'angular2/src/facade/lang';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {AnchorBasedAppRootUrl} from 'angular2/src/compiler/anchor_based_app_root_url';
import {AppRootUrl} from 'angular2/src/compiler/app_root_url';
import {
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ComponentRef,
platform,
ExceptionHandler,
Reflector,
reflector,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
Renderer,
PLATFORM_INITIALIZER,
APP_INITIALIZER
} from 'angular2/core';
import {EVENT_MANAGER_PLUGINS, EventManager} from 'angular2/platform/common_dom';
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
// TODO change these imports once dom_adapter is moved out of core
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
import {KeyEventsPlugin} from 'angular2/src/platform/dom/events/key_events';
import {HammerGesturesPlugin} from 'angular2/src/platform/dom/events/hammer_gestures';
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
import {DomRenderer, DomRenderer_} from 'angular2/src/platform/dom/dom_renderer';
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
import {SharedStylesHost} from "angular2/src/platform/dom/shared_styles_host";
import {BrowserDetails} from 'angular2/src/animate/browser_details';
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
import {XHR} from 'angular2/compiler';
import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
import {Testability} from 'angular2/src/core/testability/testability';
import {BrowserGetTestability} from 'angular2/src/platform/browser/testability';
import {BrowserDomAdapter} from './browser/browser_adapter';
import {wtfInit} from 'angular2/src/core/profile/wtf_init';
import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup';
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/service_message_broker';
import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/client_message_broker';
import {Serializer} from 'angular2/src/web_workers/shared/serializer';
import {ON_WEB_WORKER} from 'angular2/src/web_workers/shared/api';
import {RenderProtoViewRefStore} from 'angular2/src/web_workers/shared/render_proto_view_ref_store';
import {
RenderViewWithFragmentsStore
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
export const WORKER_SCRIPT: OpaqueToken = CONST_EXPR(new OpaqueToken("WebWorkerScript"));
// Message based Worker classes that listen on the MessageBus
export const WORKER_RENDER_MESSAGING_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
CONST_EXPR([MessageBasedRenderer, MessageBasedXHRImpl, WebWorkerSetup]);
export const WORKER_RENDER_PLATFORM: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
PLATFORM_COMMON_PROVIDERS,
new Provider(PLATFORM_INITIALIZER, {useValue: initWebWorkerRenderPlatform, multi: true})
]);
export const WORKER_RENDER_APP_COMMON: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
APPLICATION_COMMON_PROVIDERS,
WORKER_RENDER_MESSAGING_PROVIDERS,
new Provider(ExceptionHandler, {useFactory: _exceptionHandler, deps: []}),
new Provider(DOCUMENT, {useFactory: _document, deps: []}),
// TODO(jteplitz602): Investigate if we definitely need EVENT_MANAGER on the render thread
// #5298
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}),
new Provider(EVENT_MANAGER_PLUGINS, {useClass: KeyEventsPlugin, multi: true}),
new Provider(EVENT_MANAGER_PLUGINS, {useClass: HammerGesturesPlugin, multi: true}),
new Provider(DomRenderer, {useClass: DomRenderer_}),
new Provider(Renderer, {useExisting: DomRenderer}),
new Provider(SharedStylesHost, {useExisting: DomSharedStylesHost}),
new Provider(XHR, {useClass: XHRImpl}),
MessageBasedXHRImpl,
new Provider(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}),
new Provider(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}),
AnchorBasedAppRootUrl,
new Provider(AppRootUrl, {useExisting: AnchorBasedAppRootUrl}),
Serializer,
new Provider(ON_WEB_WORKER, {useValue: false}),
RenderViewWithFragmentsStore,
RenderProtoViewRefStore,
DomSharedStylesHost,
Testability,
BrowserDetails,
AnimationBuilder,
EventManager
]);
export function initializeGenericWorkerRenderer(injector: Injector) {
var bus = injector.get(MessageBus);
let zone = injector.get(NgZone);
bus.attachToZone(zone);
zone.run(() => {
WORKER_RENDER_MESSAGING_PROVIDERS.forEach((token) => { injector.get(token).start(); });
});
}
export function initWebWorkerRenderPlatform(): void {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(DOM, false);
}
function _document(): any {
return DOM.defaultDoc();
}

View File

@ -57,16 +57,17 @@ class MultiClientServerMessageBus extends GenericMessageBus {
}
class WebSocketWrapper {
WebSocket socket;
WebSocket _socket;
Stream stream;
int _numResultsReceived = 0;
bool _isPrimary = false;
bool caughtUp = false;
List<String> _messageHistory;
List<int> _resultMarkers;
StreamController<String> _sendStream;
WebSocketWrapper(this._messageHistory, this._resultMarkers, this.socket) {
stream = socket.asBroadcastStream();
WebSocketWrapper(this._messageHistory, this._resultMarkers, this._socket) {
stream = _socket.asBroadcastStream();
stream.listen((encodedMessage) {
var messages = JSON.decode(encodedMessage);
messages.forEach((data) {
@ -78,6 +79,13 @@ class WebSocketWrapper {
}
});
});
_sendStream = new StreamController<String>();
_socket.addStream(_sendStream.stream);
}
void send (String data) {
_sendStream.add(data);
}
bool get isPrimary => _isPrimary;
@ -113,7 +121,7 @@ class WebSocketWrapper {
numMessages = end - curr;
}
while (numMessages > 0) {
socket.add(_messageHistory[curr]);
send(_messageHistory[curr]);
curr++;
numMessages--;
}
@ -144,7 +152,7 @@ class MultiClientServerMessageBusSink extends GenericMessageBusSink {
String encodedMessages = JSON.encode(messages);
openConnections.forEach((WebSocketWrapper webSocket) {
if (webSocket.caughtUp) {
webSocket.socket.add(encodedMessages);
webSocket.send(encodedMessages);
}
});
messageHistory.add(encodedMessages);

View File

@ -1,56 +0,0 @@
library angular2.src.web_workers.ui;
import 'dart:isolate';
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, WebWorkerApplication;
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
/**
* Bootstrapping a WebWorker
*
* 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<IsolateInstance> 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<IsolateInstance> spawnWebWorker(Uri uri) async {
var receivePort = new ReceivePort();
var isolateEndSendPort = receivePort.sendPort;
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 {
UIMessageBusSource(ReceivePort port) : super(port);
Future<SendPort> get sink => stream.firstWhere((message) {
return message is SendPort;
});
}
/**
* Wrapper class that exposes the {@link WebWorkerApplication}
* Isolate instance and underlying {@link MessageBus} for lower level message passing.
*/
class IsolateInstance {
WebWorkerApplication app;
final Isolate isolate;
final MessageBus bus;
IsolateInstance(this.app, this.isolate, this.bus);
}

View File

@ -1,40 +0,0 @@
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from 'angular2/src/web_workers/shared/post_message_bus';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
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';
/**
* Bootstrapping a WebWorker
*
* 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
*/
export function bootstrap(uri: string): WebWorkerInstance {
var instance = spawnWebWorker(uri);
instance.app = bootstrapUICommon(instance.bus);
return instance;
}
export function spawnWebWorker(uri: string): WebWorkerInstance {
var webWorker: Worker = new Worker(uri);
var sink = new PostMessageBusSink(webWorker);
var source = new PostMessageBusSource(webWorker);
var bus = new PostMessageBus(sink, source);
return new WebWorkerInstance(null, webWorker, bus);
}
/**
* Wrapper class that exposes the {@link WebWorkerApplication}
* Isolate instance and underlying {@link MessageBus} for lower level message passing.
*/
export class WebWorkerInstance {
constructor(public app: WebWorkerApplication, public worker: Worker, public bus: MessageBus) {}
}

View File

@ -1,122 +0,0 @@
// TODO (jteplitz602): This whole file is nearly identical to core/application.ts.
// There should be a way to refactor application so that this file is unnecessary. See #3277
import {Injector, provide, Provider} from "angular2/src/core/di";
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
import {BrowserDetails} from 'angular2/src/animate/browser_details';
import {Reflector, reflector} from 'angular2/src/core/reflection/reflection';
import {Parser, Lexer} from 'angular2/src/core/change_detection/change_detection';
import {EventManager, EVENT_MANAGER_PLUGINS} from 'angular2/platform/common_dom';
import {ProtoViewFactory} from 'angular2/src/core/linker/proto_view_factory';
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
import {KeyEventsPlugin} from 'angular2/src/platform/dom/events/key_events';
import {HammerGesturesPlugin} from 'angular2/src/platform/dom/events/hammer_gestures';
import {AppViewPool, APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/linker/view_pool';
import {Renderer} from 'angular2/src/core/render/api';
import {AppRootUrl} from 'angular2/src/compiler/app_root_url';
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
import {DomRenderer, DomRenderer_} from 'angular2/src/platform/dom/dom_renderer';
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
import {APP_ID_RANDOM_PROVIDER} from 'angular2/src/core/application_tokens';
import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry';
import {DomElementSchemaRegistry} from 'angular2/src/compiler/schema/dom_element_schema_registry';
import {SharedStylesHost, DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {AppViewManager, AppViewManager_} from 'angular2/src/core/linker/view_manager';
import {AppViewManagerUtils} from 'angular2/src/core/linker/view_manager_utils';
import {AppViewListener} from 'angular2/src/core/linker/view_listener';
import {ViewResolver} from 'angular2/src/core/linker/view_resolver';
import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
import {ExceptionHandler} from 'angular2/src/facade/exceptions';
import {
DynamicComponentLoader,
DynamicComponentLoader_
} from 'angular2/src/core/linker/dynamic_component_loader';
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
import {Testability} from 'angular2/src/core/testability/testability';
import {XHR} from 'angular2/src/compiler/xhr';
import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
import {Serializer} from 'angular2/src/web_workers/shared/serializer';
import {ON_WEB_WORKER} from 'angular2/src/web_workers/shared/api';
import {RenderProtoViewRefStore} from 'angular2/src/web_workers/shared/render_proto_view_ref_store';
import {
RenderViewWithFragmentsStore
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
import {AnchorBasedAppRootUrl} from 'angular2/src/compiler/anchor_based_app_root_url';
import {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
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,
ServiceMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/service_message_broker';
import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/client_message_broker';
import {PLATFORM_DIRECTIVES, PLATFORM_PIPES} from "angular2/src/core/platform_directives_and_pipes";
import {COMMON_DIRECTIVES, COMMON_PIPES} from "angular2/common";
var _rootInjector: Injector;
// Contains everything that is safe to share between applications.
var _rootProviders = [provide(Reflector, {useValue: reflector})];
// TODO: This code is nearly identical to core/application. There should be a way to only write it
// once
function _injectorProviders(): any[] {
return [
provide(DOCUMENT, {useValue: DOM.defaultDoc()}),
EventManager,
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}),
new Provider(EVENT_MANAGER_PLUGINS, {useClass: KeyEventsPlugin, multi: true}),
new Provider(EVENT_MANAGER_PLUGINS, {useClass: HammerGesturesPlugin, multi: true}),
provide(DomRenderer, {useClass: DomRenderer_}),
provide(Renderer, {useExisting: DomRenderer}),
APP_ID_RANDOM_PROVIDER,
DomSharedStylesHost,
provide(SharedStylesHost, {useExisting: DomSharedStylesHost}),
Serializer,
provide(ON_WEB_WORKER, {useValue: false}),
provide(ElementSchemaRegistry, {useValue: new DomElementSchemaRegistry()}),
RenderViewWithFragmentsStore,
RenderProtoViewRefStore,
AppViewPool,
provide(APP_VIEW_POOL_CAPACITY, {useValue: 10000}),
provide(AppViewManager, {useClass: AppViewManager_}),
AppViewManagerUtils,
AppViewListener,
ProtoViewFactory,
ViewResolver,
provide(PLATFORM_PIPES, {useValue: COMMON_PIPES, multi: true}),
provide(PLATFORM_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}),
DirectiveResolver,
Parser,
Lexer,
provide(ExceptionHandler, {useFactory: () => new ExceptionHandler(DOM), deps: []}),
provide(XHR, {useValue: new XHRImpl()}),
UrlResolver,
provide(DynamicComponentLoader, {useClass: DynamicComponentLoader_}),
Testability,
AnchorBasedAppRootUrl,
provide(AppRootUrl, {useExisting: AnchorBasedAppRootUrl}),
WebWorkerApplication,
WebWorkerSetup,
MessageBasedXHRImpl,
MessageBasedRenderer,
provide(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}),
provide(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}),
BrowserDetails,
AnimationBuilder
];
}
export function createInjector(zone: NgZone, bus: MessageBus): Injector {
BrowserDomAdapter.makeCurrent();
_rootProviders.push(provide(NgZone, {useValue: zone}));
_rootProviders.push(provide(MessageBus, {useValue: bus}));
var injector: Injector = Injector.resolveAndCreate(_rootProviders);
return injector.resolveAndCreateChild(_injectorProviders());
}

View File

@ -1,56 +0,0 @@
/*
* This file is the entry point for the main thread
* It takes care of spawning the worker and sending it the initial init message
* It also acts and the messenger between the worker thread and the renderer running on the UI
* thread
*/
import {createInjector} from "./di_bindings";
import {MessageBus, MessageBusSink} from "angular2/src/web_workers/shared/message_bus";
import {createNgZone} from 'angular2/src/core/application_ref';
import {Injectable} from 'angular2/src/core/di';
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
import {wtfInit} from 'angular2/src/core/profile/wtf_init';
import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup';
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 providers
* And then creates a new WebWorkerMain object to handle messages from the worker
*/
export function bootstrapUICommon(bus: MessageBus): WebWorkerApplication {
BrowserDomAdapter.makeCurrent();
var zone = createNgZone();
wtfInit();
bus.attachToZone(zone);
return zone.run(() => {
var injector = createInjector(zone, bus);
injector.get(MessageBasedRenderer).start();
injector.get(MessageBasedXHRImpl).start();
injector.get(WebWorkerSetup).start();
return injector.get(WebWorkerApplication);
});
}
@Injectable()
export class WebWorkerApplication {
constructor(private _clientMessageBrokerFactory: ClientMessageBrokerFactory,
private _serviceMessageBrokerFactory: ServiceMessageBrokerFactory) {}
createClientMessageBroker(channel: string, runInZone: boolean = true): ClientMessageBroker {
return this._clientMessageBrokerFactory.createMessageBroker(channel, runInZone);
}
createServiceMessageBroker(channel: string, runInZone: boolean = true): ServiceMessageBroker {
return this._serviceMessageBrokerFactory.createMessageBroker(channel, runInZone);
}
}

View File

@ -1,41 +0,0 @@
library angular2.src.web_workers.worker;
import "package:angular2/src/web_workers/shared/isolate_message_bus.dart";
import "package:angular2/src/web_workers/worker/application_common.dart"
show bootstrapWebWorkerCommon;
import "package:angular2/src/facade/async.dart" show Future;
import "package:angular2/src/facade/lang.dart" show Type, BaseException;
import "package:angular2/src/core/linker/dynamic_component_loader.dart"
show ComponentRef;
import "dart:isolate";
import "dart:async";
import 'dart:core';
import 'package:angular2/src/platform/server/webworker_adapter.dart';
/**
* Bootstrapping a Webworker Application
*
* You instantiate the application side by calling bootstrapWebworker from your webworker index
* script.
* You must supply a SendPort for communicating with the UI side in order to instantiate
* the application.
* Other than the SendPort you can call bootstrapWebworker() exactly as you would call
* bootstrap() in a regular Angular application
* See the bootstrap() docs for more details.
*/
Future<ComponentRef> bootstrapWebWorker(SendPort replyTo, Type appComponentType,
[List<dynamic> componentInjectableBindings = null]) {
WebWorkerDomAdapter.makeCurrent();
ReceivePort rPort = new ReceivePort();
var sink = new WebWorkerMessageBusSink(replyTo, rPort);
var source = new IsolateMessageBusSource(rPort);
IsolateMessageBus bus = new IsolateMessageBus(sink, source);
return bootstrapWebWorkerCommon(
appComponentType, bus, componentInjectableBindings);
}
class WebWorkerMessageBusSink extends IsolateMessageBusSink {
WebWorkerMessageBusSink(SendPort sPort, ReceivePort rPort) : super(sPort) {
sPort.send(rPort.sendPort);
}
}

View File

@ -1,42 +0,0 @@
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from 'angular2/src/web_workers/shared/post_message_bus';
import {Type} from "angular2/src/facade/lang";
import {Provider, Injectable} from "angular2/src/core/di";
import {Map} from 'angular2/src/facade/collection';
import {Promise} from 'angular2/src/facade/async';
import {bootstrapWebWorkerCommon} from "angular2/src/web_workers/worker/application_common";
import {ComponentRef} from "angular2/src/core/linker/dynamic_component_loader";
export * from "angular2/src/web_workers/shared/message_bus";
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
interface PostMessageInterface {
(message: any, transferrables?:[ArrayBuffer]): void;
}
var _postMessage: PostMessageInterface = <any>postMessage;
/**
* Bootstrapping a Webworker Application
*
* You instantiate the application side by calling bootstrapWebworker from your webworker index
* script.
* You can call bootstrapWebworker() exactly as you would call bootstrap() in a regular Angular
* application
* See the bootstrap() docs for more details.
*/
export function bootstrapWebWorker(
appComponentType: Type,
componentInjectableProviders: Array<Type | Provider | any[]> = null): Promise<ComponentRef> {
Parse5DomAdapter.makeCurrent();
var sink = new PostMessageBusSink({
postMessage:
(message: any, transferrables?:[ArrayBuffer]) => { _postMessage(message, transferrables); }
});
var source = new PostMessageBusSource();
var bus = new PostMessageBus(sink, source);
return bootstrapWebWorkerCommon(appComponentType, bus, componentInjectableProviders);
}

View File

@ -1,147 +0,0 @@
import {Injector, provide, OpaqueToken, Provider} from 'angular2/src/core/di';
import {FORM_PROVIDERS} from 'angular2/src/common/forms';
import {
NumberWrapper,
Type,
isBlank,
isPresent,
assertionsEnabled,
print,
stringify
} from 'angular2/src/facade/lang';
import {ExceptionHandler} from 'angular2/src/facade/exceptions';
import {Promise, PromiseWrapper, PromiseCompleter} from 'angular2/src/facade/async';
import {XHR} from 'angular2/src/compiler/xhr';
import {WebWorkerXHRImpl} from 'angular2/src/web_workers/worker/xhr_impl';
import {AppRootUrl} from 'angular2/src/compiler/app_root_url';
import {WebWorkerRenderer} from './renderer';
import {Renderer} from 'angular2/src/core/render/api';
import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/client_message_broker';
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/service_message_broker';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {
PlatformRef,
ApplicationRef,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS
} from 'angular2/core';
import * as core from 'angular2/core';
import {Serializer} from "angular2/src/web_workers/shared/serializer";
import {ON_WEB_WORKER} from "angular2/src/web_workers/shared/api";
import {RenderProtoViewRefStore} from 'angular2/src/web_workers/shared/render_proto_view_ref_store';
import {
RenderViewWithFragmentsStore
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
import {ObservableWrapper} from 'angular2/src/facade/async';
import {SETUP_CHANNEL} from 'angular2/src/web_workers/shared/messaging_api';
import {WebWorkerEventDispatcher} from 'angular2/src/web_workers/worker/event_dispatcher';
import {ComponentRef} from 'angular2/src/core/linker/dynamic_component_loader';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
/**
* Initialize the Angular 'platform' on the page in a manner suitable for applications
* running in a web worker. Applications running on a web worker do not have direct
* access to DOM APIs.
*
* See {@link PlatformRef} for details on the Angular platform.
*
* ### Without specified providers
*
* If no providers are specified, `platform`'s behavior depends on whether an existing
* platform exists:
*
* If no platform exists, a new one will be created with the default {@link platformProviders}.
*
* If a platform already exists, it will be returned (regardless of what providers it
* was created with). This is a convenience feature, allowing for multiple applications
* to be loaded into the same platform without awareness of each other.
*
* ### With specified providers
*
* It is also possible to specify providers to be made in the new platform. These providers
* will be shared between all applications on the page. For example, an abstraction for
* the browser cookie jar should be bound at the platform level, because there is only one
* cookie jar regardless of how many applications on the age will be accessing it.
*
* If providers are specified directly, `platform` will create the Angular platform with
* them if a platform did not exist already. If it did exist, however, an error will be
* thrown.
*
* ### For Web Worker Applications
*
* This version of `platform` initializes Angular for use with applications
* that do not directly touch the DOM, such as applications which run in a
* web worker context. Applications that need direct access to the DOM should
* use `platform` from `core/application_common` instead.
*/
export function platform(providers?: Array<Type | Provider | any[]>): PlatformRef {
let platformProviders =
isPresent(providers) ? [PLATFORM_COMMON_PROVIDERS, providers] : PLATFORM_COMMON_PROVIDERS;
return core.platform(platformProviders);
}
class PrintLogger {
log = print;
logError = print;
logGroup = print;
logGroupEnd() {}
}
function webWorkerProviders(appComponentType, bus: MessageBus,
initData: {[key: string]: any}): Array<Type | Provider | any[]> {
return [
COMPILER_PROVIDERS,
Serializer,
provide(MessageBus, {useValue: bus}),
provide(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}),
provide(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}),
WebWorkerRenderer,
provide(Renderer, {useExisting: WebWorkerRenderer}),
provide(ON_WEB_WORKER, {useValue: true}),
RenderViewWithFragmentsStore,
RenderProtoViewRefStore,
provide(ExceptionHandler,
{useFactory: () => new ExceptionHandler(new PrintLogger()), deps: []}),
WebWorkerXHRImpl,
provide(XHR, {useExisting: WebWorkerXHRImpl}),
provide(AppRootUrl, {useValue: new AppRootUrl(initData['rootUrl'])}),
WebWorkerEventDispatcher,
FORM_PROVIDERS
];
}
export function bootstrapWebWorkerCommon(
appComponentType: Type, bus: MessageBus,
appProviders: Array<Type | Provider | any[]> = null): Promise<ComponentRef> {
var bootstrapProcess: PromiseCompleter<any> = PromiseWrapper.completer();
var appPromise = platform().asyncApplication((zone: NgZone) => {
// TODO(rado): prepopulate template cache, so applications with only
// index.html and main.js are possible.
//
bus.attachToZone(zone);
bus.initChannel(SETUP_CHANNEL, false);
var subscription: any;
var emitter = bus.from(SETUP_CHANNEL);
subscription = ObservableWrapper.subscribe(emitter, (message: {[key: string]: any}) => {
var bindings =
[APPLICATION_COMMON_PROVIDERS, webWorkerProviders(appComponentType, bus, message)];
if (isPresent(appProviders)) {
bindings.push(appProviders);
}
bootstrapProcess.resolve(bindings);
ObservableWrapper.dispose(subscription);
});
ObservableWrapper.callEmit(bus.to(SETUP_CHANNEL), "ready");
return bootstrapProcess.promise;
});
return PromiseWrapper.then(appPromise, (app) => app.bootstrap(appComponentType));
}

View File

@ -14,8 +14,11 @@ import {
inject
} from 'angular2/testing_internal';
import {SpyChangeDetector} from './spies';
import {ApplicationRef_} from "angular2/src/core/application_ref";
import {ApplicationRef_, PlatformRef_} from "angular2/src/core/application_ref";
import {Injector, Provider} from "angular2/core";
import {ChangeDetectorRef_} from "angular2/src/core/change_detection/change_detector_ref";
import {PromiseWrapper} from "angular2/src/facade/async";
import {ListWrapper} from "angular2/src/facade/collection";
export function main() {
describe("ApplicationRef", () => {
@ -27,4 +30,32 @@ export function main() {
expect(() => ref.tick()).toThrowError("ApplicationRef.tick is called recursively");
});
});
describe("PlatformRef", () => {
describe("asyncApplication", () => {
it("should merge syncronous and asyncronous providers",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()})];
let SYNC_PROVIDERS = [new Provider(Bar, {useValue: new Bar()})];
ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS), SYNC_PROVIDERS)
.then((appRef) => {
var providers = ListWrapper.concat(ASYNC_PROVIDERS, SYNC_PROVIDERS);
for (var i = 0; i < providers.length; i++) {
var provider = providers[i];
expect(appRef.injector.get(provider.token)).toBe(provider.useValue);
}
async.done();
});
}));
});
});
}
class Foo {
constructor() {}
}
class Bar {
constructor() {}
}

View File

@ -4,8 +4,9 @@ import 'package:angular2/src/platform/server/html_adapter.dart';
import "package:angular2/testing_internal.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/web_worker/worker.dart";
import "package:angular2/src/web_workers/worker/application_common.dart";
import "package:angular2/src/platform/worker_app_common.dart" show WORKER_APP_COMMON_PROVIDERS;
import "package:angular2/platform/worker_app.dart" show WORKER_APP_PLATFORM;
import "package:angular2/core.dart";
import "../shared/web_worker_test_util.dart";
import "dart:convert";
@ -13,17 +14,12 @@ main() {
Html5LibDomAdapter.makeCurrent();
testSetup();
describe("bootstrapWebWorkerCommon", () {
it("should bootstrap on a Dart VM", () {
describe("WORKER_APP_COMMON_PROVIDERS", () {
it("should be able to load in a Dart VM", () {
reflector.reflectionCapabilities = new ReflectionCapabilities();
var buses = createPairedMessageBuses();
bootstrapWebWorkerCommon(App, buses.worker);
platform([WORKER_APP_PLATFORM])
.application([WORKER_APP_COMMON_PROVIDERS]);
});
});
}
@Component(selector: "app")
@View(template: "<p>Hello {{name}}</p>")
class App {
String name = "Tester";
}

View File

@ -213,6 +213,7 @@ SpySocketWrapper createSocket({Function messageHandler}) {
var socket = new SpyWebSocket();
if (messageHandler != null) {
socket.spy("add").andCallFake(messageHandler);
socket.spy("addStream").andCallFake((Stream stream) => stream.listen(messageHandler));
}
var controller = new StreamController<String>.broadcast();

View File

@ -49,7 +49,6 @@ import {
RenderViewWithFragmentsStore,
WebWorkerRenderViewRef
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
import {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
import {createPairedMessageBuses, PairedMessageBuses} from '../shared/web_worker_test_util';
import {
@ -76,7 +75,6 @@ export function main() {
var renderer = new MessageBasedRenderer(uiMessageBrokerFactory, uiMessageBus, uiSerializer,
uiRenderProtoViewStore, uiRenderViewStore, domRenderer);
renderer.start();
new WebWorkerApplication(null, null);
return webWorkerBrokerFactory;
}

View File

@ -1,15 +1,11 @@
export * from 'angular2/src/facade/facade';
export * from '../src/core/di';
export {platform, PlatformRef, ApplicationRef} from '../src/core/application_ref';
export {
APP_ID,
APP_COMPONENT,
APP_INITIALIZER,
PLATFORM_INITIALIZER
} from '../src/core/application_tokens';
export * from '../src/core/zone';
export * from "../src/web_workers/ui/application";
export {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from "../src/web_workers/shared/client_message_broker";
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from "../src/web_workers/shared/service_message_broker";
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
export * from 'angular2/platform/worker_render';

View File

@ -1,55 +1,6 @@
export * from '../src/core/linker/interfaces';
export * from '../src/core/metadata';
export * from '../src/core/util';
export * from '../src/core/di';
export * from '../src/common/pipes';
export * from 'angular2/src/facade/facade';
// Do not export application in web_worker,
// web_worker exports its own
// export * from '../src/core/application';
export * from '../src/core/application_ref';
export * from '../src/platform/browser/ruler';
export * from '../src/platform/browser/title';
export * from '../src/compiler/url_resolver';
export * from '../src/core/linker';
export * from '../src/core/zone';
// Do not export render in web_worker
// export * from '../src/core/render';
// Add special import for just render API
// TODO: Hard coded exports from render that need to be cleaned up
export {
RenderEventDispatcher,
Renderer,
RenderElementRef,
RenderViewRef,
RenderProtoViewRef,
RenderFragmentRef,
RenderViewWithFragments,
RenderTemplateCmd,
RenderCommandVisitor,
RenderTextCmd,
RenderNgContentCmd,
RenderBeginElementCmd,
RenderBeginComponentCmd,
RenderEmbeddedTemplateCmd,
RenderBeginCmd
} from '../src/core/render/api';
export * from '../src/common/directives';
export * from '../src/common/forms';
export {DebugElement} from '../src/core/debug/debug_element';
export * from '../src/core/change_detection';
export * from '../common';
export * from '../core';
export * from '../platform/worker_app';
export {UrlResolver, AppRootUrl} from '../compiler';
export * from '../instrumentation';
export * from '../src/web_workers/worker/application';
export {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from '../src/web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from '../src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
export * from 'angular2/src/platform/worker_app';

View File

@ -2,12 +2,14 @@ library playground.src.web_workers.images.background_index;
import "index_common.dart" show ImageDemo;
import "dart:isolate";
import "package:angular2/src/web_workers/worker/application.dart"
show bootstrapWebWorker;
import "package:angular2/platform/worker_app.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrapWebWorker(replyTo, ImageDemo).catchError((error) => throw error);
}
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupIsolate(replyTo))
.then((ref) => ref.bootstrap(ImageDemo));
}

View File

@ -1,6 +1,9 @@
import {bootstrapWebWorker} from "angular2/src/web_workers/worker/application";
import {ImageDemo} from "./index_common";
import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app";
export function main() {
bootstrapWebWorker(ImageDemo);
}
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(ImageDemo));
}

View File

@ -1,10 +1,12 @@
library angular2.examples.web_workers.images.index;
import "package:angular2/src/web_workers/ui/application.dart" show bootstrap;
import "package:angular2/platform/worker_render.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrap("background_index.dart");
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("background_index.dart"));
}

View File

@ -1,2 +1,9 @@
import {bootstrap} from "angular2/src/web_workers/ui/application";
bootstrap("loader.js");
import {platform, Provider} from 'angular2/core';
import {
WORKER_RENDER_APP,
WORKER_RENDER_PLATFORM,
WORKER_SCRIPT
} from 'angular2/platform/worker_render';
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APP, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]);

View File

@ -2,12 +2,14 @@ library playground.src.web_workers.kitchen_sink.background_index;
import "index_common.dart" show HelloCmp;
import "dart:isolate";
import "package:angular2/src/web_workers/worker/application.dart"
show bootstrapWebWorker;
import "package:angular2/platform/worker_app.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrapWebWorker(replyTo, HelloCmp).catchError((error) => throw error);
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupIsolate(replyTo))
.then((ref) => ref.bootstrap(HelloCmp));
}

View File

@ -1,6 +1,9 @@
import {HelloCmp} from "./index_common";
import {bootstrapWebWorker} from "angular2/src/web_workers/worker/application";
import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app";
export function main() {
bootstrapWebWorker(HelloCmp);
}
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(HelloCmp));
}

View File

@ -1,10 +1,12 @@
library angular2.examples.web_workers.kitchen_sink.index;
import "package:angular2/src/web_workers/ui/application.dart" show bootstrap;
import "package:angular2/platform/worker_render.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrap("background_index.dart");
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("background_index.dart"));
}

View File

@ -1,2 +1,9 @@
import {bootstrap} from "angular2/src/web_workers/ui/application";
bootstrap("loader.js");
import {platform, Provider} from 'angular2/core';
import {
WORKER_RENDER_APP,
WORKER_RENDER_PLATFORM,
WORKER_SCRIPT
} from 'angular2/platform/worker_render';
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APP, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]);

View File

@ -1,6 +1,7 @@
library angular2.examples.message_broker.background_index;
import "package:angular2/web_worker/worker.dart";
import "package:angular2/platform/worker_app.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "index_common.dart" show App;
@ -8,5 +9,7 @@ import "dart:isolate";
main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrapWebWorker(replyTo, App).catchError((error) => throw error);
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupIsolate(replyTo))
.then((ref) => ref.bootstrap(App));
}

View File

@ -1,6 +1,9 @@
import {bootstrapWebWorker} from "angular2/web_worker/worker";
import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app";
import {App} from "./index_common";
export function main() {
bootstrapWebWorker(App);
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(App));
}

View File

@ -1,6 +1,7 @@
library angular2.examples.message_broker.index;
import "package:angular2/web_worker/ui.dart";
import "package:angular2/platform/worker_render.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "dart:html";
@ -8,8 +9,11 @@ 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, false);
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("background_index.dart"))
.then((ref) {
var brokerFactory = ref.injector.get(ClientMessageBrokerFactory);
var broker = brokerFactory.createMessageBroker(ECHO_CHANNEL, false);
querySelector("#send_echo").addEventListener("click", (e) {
var val = (querySelector("#echo_input") as InputElement).value;
var args = new UiArguments("echo", [new FnArg(val, PRIMITIVE)]);

View File

@ -1,9 +1,21 @@
import {bootstrap, UiArguments, FnArg, PRIMITIVE} from "angular2/web_worker/ui";
import {platform, Provider} from 'angular2/core';
import {
WORKER_RENDER_APP,
WORKER_RENDER_PLATFORM,
WORKER_SCRIPT,
UiArguments,
FnArg,
PRIMITIVE,
ClientMessageBrokerFactory
} from 'angular2/platform/worker_render';
const ECHO_CHANNEL = "ECHO";
var instance = bootstrap("loader.js");
var broker = instance.app.createClientMessageBroker(ECHO_CHANNEL, false);
let ref =
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APP, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]);
let brokerFactory: ClientMessageBrokerFactory = ref.injector.get(ClientMessageBrokerFactory);
var broker = brokerFactory.createMessageBroker(ECHO_CHANNEL, false);
document.getElementById("send_echo")
.addEventListener("click", (e) => {

View File

@ -1,5 +1,6 @@
import {PromiseWrapper} from "angular2/src/facade/async";
import {Component, View, ServiceMessageBrokerFactory, PRIMITIVE} from "angular2/web_worker/worker";
import {Component, View} from "angular2/core";
import {ServiceMessageBrokerFactory, PRIMITIVE} from "angular2/platform/worker_app";
const ECHO_CHANNEL = "ECHO";

View File

@ -8,7 +8,6 @@ System.config({
System.import("playground/src/web_workers/message_broker/background_index")
.then(
function(m) {
console.log("running main");
try {
m.main();
} catch (e) {

View File

@ -2,12 +2,14 @@ library playground.src.web_workers.todo.background_index;
import "index_common.dart" show TodoApp;
import "dart:isolate";
import "package:angular2/src/web_workers/worker/application.dart"
show bootstrapWebWorker;
import "package:angular2/platform/worker_app.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrapWebWorker(replyTo, TodoApp).catchError((error) => throw error);
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupIsolate(replyTo))
.then((ref) => ref.bootstrap(TodoApp));
}

View File

@ -1,6 +1,9 @@
import {bootstrapWebWorker} from "angular2/src/web_workers/worker/application";
import {TodoApp} from "./index_common";
import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app";
export function main() {
bootstrapWebWorker(TodoApp);
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(TodoApp));
}

View File

@ -1,10 +1,12 @@
library angular2.examples.web_workers.todo.index;
import "package:angular2/src/web_workers/ui/application.dart" show bootstrap;
import "package:angular2/platform/worker_render.dart";
import "package:angular2/core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
bootstrap("background_index.dart");
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("background_index.dart"));
}

View File

@ -1,2 +1,9 @@
import {bootstrap} from "angular2/src/web_workers/ui/application";
bootstrap("loader.js");
import {platform, Provider} from 'angular2/core';
import {
WORKER_RENDER_APP,
WORKER_RENDER_PLATFORM,
WORKER_SCRIPT
} from 'angular2/platform/worker_render';
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APP, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]);

View File

@ -1,4 +1,5 @@
import {NgFor, View, Component, FORM_DIRECTIVES} from 'angular2/web_worker/worker';
import {View, Component} from 'angular2/core';
import {NgFor, FORM_DIRECTIVES} from 'angular2/common';
import {Store, Todo, TodoFactory} from './services/TodoStore';
@Component({selector: 'todo-app', viewProviders: [Store, TodoFactory]})

View File

@ -2,10 +2,10 @@ library angular2.examples.web_workers.todo.index_web_socket;
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/web_workers/ui/impl.dart" show bootstrapUICommon;
import "package:angular2/core.dart";
import "package:angular2/platform/worker_render.dart";
import "package:angular2/src/web_workers/debug_tools/web_socket_message_bus.dart";
import 'dart:html'
show WebSocket;
import 'dart:html' show WebSocket;
main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
@ -13,6 +13,13 @@ main() {
webSocket.onOpen.listen((e) {
var bus = new WebSocketMessageBus.fromWebSocket(webSocket);
bootstrapUICommon(bus);
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APP_COMMON, new Provider(MessageBus, useValue: bus),
new Provider(APP_INITIALIZER,
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
deps: [Injector],
multi: true
)
]);
});
}

View File

@ -1,19 +1,28 @@
library angular2.examples.web_workers.todo.server_index;
import "index_common.dart" show TodoApp;
import "package:angular2/src/web_workers/debug_tools/multi_client_server_message_bus.dart";
import "package:angular2/src/web_workers/worker/application_common.dart"
show bootstrapWebWorkerCommon;
import "package:angular2/platform/worker_app.dart";
import "package:angular2/core.dart";
import 'dart:io';
import 'dart:async';
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/platform/server/html_adapter.dart";
void main() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM])
.asyncApplication(initAppThread)
.then((ref) => ref.bootstrap(TodoApp));
}
Future<dynamic> initAppThread(NgZone zone) {
Html5LibDomAdapter.makeCurrent();
reflector.reflectionCapabilities = new ReflectionCapabilities();
HttpServer.bind('127.0.0.1', 1337).then((HttpServer server) {
return HttpServer.bind('127.0.0.1', 1337).then((HttpServer server) {
print("Server Listening for requests on 127.0.0.1:1337");
var bus = new MultiClientServerMessageBus.fromHttpServer(server);
bootstrapWebWorkerCommon(TodoApp, bus).catchError((error) => throw error);
print ("Server Listening for requests on 127.0.0.1:1337");
return genericWorkerAppProviders(bus, zone);
});
}

View File

@ -1,4 +1,4 @@
import {Injectable} from 'angular2/web_worker/worker';
import {Injectable} from 'angular2/core';
import {ListWrapper, Predicate} from 'angular2/src/facade/collection';
// base model for RecordStore