Fixes issues in dart where dart:html is not available in isolates and allows for better profiling of XHR requests Closes #3652
200 lines
8.0 KiB
TypeScript
200 lines
8.0 KiB
TypeScript
import {Injector, bind, OpaqueToken, Binding} from 'angular2/di';
|
|
import {
|
|
NumberWrapper,
|
|
Type,
|
|
isBlank,
|
|
isPresent,
|
|
BaseException,
|
|
assertionsEnabled,
|
|
print,
|
|
stringify
|
|
} from 'angular2/src/facade/lang';
|
|
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
|
import {Reflector, reflector} from 'angular2/src/reflection/reflection';
|
|
import {
|
|
Parser,
|
|
Lexer,
|
|
ChangeDetection,
|
|
DynamicChangeDetection,
|
|
JitChangeDetection,
|
|
PreGeneratedChangeDetection,
|
|
IterableDiffers,
|
|
defaultIterableDiffers,
|
|
KeyValueDiffers,
|
|
defaultKeyValueDiffers
|
|
} from 'angular2/src/change_detection/change_detection';
|
|
import {DEFAULT_PIPES} from 'angular2/pipes';
|
|
import {StyleUrlResolver} from 'angular2/src/render/dom/compiler/style_url_resolver';
|
|
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
|
|
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
|
import {PipeResolver} from 'angular2/src/core/compiler/pipe_resolver';
|
|
import {ViewResolver} from 'angular2/src/core/compiler/view_resolver';
|
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
|
import {Promise, PromiseWrapper, PromiseCompleter} from 'angular2/src/facade/async';
|
|
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
|
import {XHR} from 'angular2/src/render/xhr';
|
|
import {WebWorkerXHRImpl} from 'angular2/src/web-workers/worker/xhr_impl';
|
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
|
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
|
import {AppRootUrl} from 'angular2/src/services/app_root_url';
|
|
import {
|
|
ComponentRef,
|
|
DynamicComponentLoader
|
|
} from 'angular2/src/core/compiler/dynamic_component_loader';
|
|
import {Testability} from 'angular2/src/core/testability/testability';
|
|
import {AppViewPool, APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_pool';
|
|
import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
|
|
import {AppViewManagerUtils} from 'angular2/src/core/compiler/view_manager_utils';
|
|
import {AppViewListener} from 'angular2/src/core/compiler/view_listener';
|
|
import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
|
|
import {WebWorkerRenderer, WebWorkerCompiler} from './renderer';
|
|
import {Renderer, RenderCompiler} from 'angular2/src/render/api';
|
|
import {internalView} from 'angular2/src/core/compiler/view_ref';
|
|
|
|
import {MessageBroker} from 'angular2/src/web-workers/worker/broker';
|
|
import {WebWorkerMessageBus} from 'angular2/src/web-workers/worker/application';
|
|
import {APP_COMPONENT_REF_PROMISE, APP_COMPONENT} from 'angular2/src/core/application_tokens';
|
|
import {ApplicationRef} from 'angular2/src/core/application';
|
|
import {createNgZone} from 'angular2/src/core/application_common';
|
|
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';
|
|
|
|
var _rootInjector: Injector;
|
|
|
|
// Contains everything that is safe to share between applications.
|
|
var _rootBindings = [bind(Reflector).toValue(reflector)];
|
|
|
|
class PrintLogger {
|
|
log = print;
|
|
logGroup = print;
|
|
logGroupEnd() {}
|
|
}
|
|
|
|
function _injectorBindings(appComponentType, bus: WebWorkerMessageBus,
|
|
initData: StringMap<string, any>): List<Type | Binding | List<any>> {
|
|
var bestChangeDetection: Type = DynamicChangeDetection;
|
|
if (PreGeneratedChangeDetection.isSupported()) {
|
|
bestChangeDetection = PreGeneratedChangeDetection;
|
|
} else if (JitChangeDetection.isSupported()) {
|
|
bestChangeDetection = JitChangeDetection;
|
|
}
|
|
return [
|
|
bind(APP_COMPONENT)
|
|
.toValue(appComponentType),
|
|
bind(APP_COMPONENT_REF_PROMISE)
|
|
.toFactory(
|
|
(dynamicComponentLoader, injector) => {
|
|
|
|
// TODO(rado): investigate whether to support bindings on root component.
|
|
return dynamicComponentLoader.loadAsRoot(appComponentType, null, injector)
|
|
.then((componentRef) => { return componentRef; });
|
|
},
|
|
[DynamicComponentLoader, Injector]),
|
|
|
|
bind(appComponentType).toFactory((ref) => ref.instance, [APP_COMPONENT_REF_PROMISE]),
|
|
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(null, assertionsEnabled()),
|
|
[ExceptionHandler]),
|
|
Serializer,
|
|
bind(WebWorkerMessageBus).toValue(bus),
|
|
bind(MessageBroker)
|
|
.toFactory((a, b, c) => new MessageBroker(a, b, c),
|
|
[WebWorkerMessageBus, Serializer, NgZone]),
|
|
WebWorkerRenderer,
|
|
bind(Renderer).toAlias(WebWorkerRenderer),
|
|
WebWorkerCompiler,
|
|
bind(RenderCompiler).toAlias(WebWorkerCompiler),
|
|
bind(ON_WEB_WORKER).toValue(true),
|
|
RenderViewWithFragmentsStore,
|
|
RenderProtoViewRefStore,
|
|
ProtoViewFactory,
|
|
AppViewPool,
|
|
bind(APP_VIEW_POOL_CAPACITY).toValue(10000),
|
|
AppViewManager,
|
|
AppViewManagerUtils,
|
|
AppViewListener,
|
|
Compiler,
|
|
CompilerCache,
|
|
ViewResolver,
|
|
DEFAULT_PIPES,
|
|
bind(IterableDiffers).toValue(defaultIterableDiffers),
|
|
bind(KeyValueDiffers).toValue(defaultKeyValueDiffers),
|
|
bind(ChangeDetection).toClass(bestChangeDetection),
|
|
DirectiveResolver,
|
|
PipeResolver,
|
|
Parser,
|
|
Lexer,
|
|
bind(ExceptionHandler).toFactory(() => new ExceptionHandler(new PrintLogger()), []),
|
|
WebWorkerXHRImpl,
|
|
bind(XHR).toAlias(WebWorkerXHRImpl),
|
|
ComponentUrlMapper,
|
|
UrlResolver,
|
|
StyleUrlResolver,
|
|
DynamicComponentLoader,
|
|
Testability,
|
|
bind(AppRootUrl).toValue(new AppRootUrl(initData['rootUrl']))
|
|
];
|
|
}
|
|
|
|
export function bootstrapWebWorkerCommon(
|
|
appComponentType: Type, bus: WebWorkerMessageBus,
|
|
componentInjectableBindings: List<Type | Binding | List<any>> = null): Promise<ApplicationRef> {
|
|
var bootstrapProcess: PromiseCompleter<any> = PromiseWrapper.completer();
|
|
|
|
var zone = createNgZone();
|
|
zone.run(() => {
|
|
// TODO(rado): prepopulate template cache, so applications with only
|
|
// index.html and main.js are possible.
|
|
//
|
|
|
|
var listenerId: int;
|
|
listenerId = bus.source.addListener((message: StringMap<string, any>) => {
|
|
if (message["data"]["type"] !== "init") {
|
|
return;
|
|
}
|
|
|
|
var appInjector = _createAppInjector(appComponentType, componentInjectableBindings, zone, bus,
|
|
message["data"]["value"]);
|
|
var compRefToken = PromiseWrapper.wrap(() => {
|
|
try {
|
|
return appInjector.get(APP_COMPONENT_REF_PROMISE);
|
|
} catch (e) {
|
|
throw e;
|
|
}
|
|
});
|
|
var tick = (componentRef) => {
|
|
var appChangeDetector = internalView(componentRef.hostView).changeDetector;
|
|
// retrieve life cycle: may have already been created if injected in root component
|
|
var lc = appInjector.get(LifeCycle);
|
|
lc.registerWith(zone, appChangeDetector);
|
|
lc.tick(); // the first tick that will bootstrap the app
|
|
|
|
bootstrapProcess.resolve(new ApplicationRef(componentRef, appComponentType, appInjector));
|
|
};
|
|
PromiseWrapper.then(compRefToken, tick,
|
|
(err, stackTrace) => { bootstrapProcess.reject(err, stackTrace); });
|
|
|
|
bus.source.removeListener(listenerId);
|
|
});
|
|
|
|
bus.sink.send({'type': "ready"});
|
|
});
|
|
|
|
return bootstrapProcess.promise;
|
|
}
|
|
|
|
function _createAppInjector(appComponentType: Type, bindings: List<Type | Binding | List<any>>,
|
|
zone: NgZone, bus: WebWorkerMessageBus,
|
|
initData: StringMap<string, any>): Injector {
|
|
if (isBlank(_rootInjector)) _rootInjector = Injector.resolveAndCreate(_rootBindings);
|
|
var mergedBindings: any[] =
|
|
isPresent(bindings) ?
|
|
ListWrapper.concat(_injectorBindings(appComponentType, bus, initData), bindings) :
|
|
_injectorBindings(appComponentType, bus, initData);
|
|
mergedBindings.push(bind(NgZone).toValue(zone));
|
|
return _rootInjector.resolveAndCreateChild(mergedBindings);
|
|
} |