feat(webworkers) Add MessageBus, Broker, and Serializer
This commit is contained in:
parent
b26f99787e
commit
33500e986b
|
@ -0,0 +1,18 @@
|
|||
// TODO(jteplitz602) to be idiomatic these should be releated to Observable's or Streams
|
||||
/**
|
||||
* Message Bus is a low level API used to communicate between the UI and the worker.
|
||||
* It smooths out the differences between Javascript's postMessage and Dart's Isolate
|
||||
* allowing you to work with one consistent API.
|
||||
*/
|
||||
export interface MessageBus {
|
||||
sink: MessageBusSink;
|
||||
source: MessageBusSource;
|
||||
}
|
||||
|
||||
export interface SourceListener {
|
||||
(data: any): void; // TODO: Replace this any type with the type of a real messaging protocol
|
||||
}
|
||||
|
||||
export interface MessageBusSource { listen(fn: SourceListener): void; }
|
||||
|
||||
export interface MessageBusSink { send(message: Object): void; }
|
|
@ -0,0 +1,271 @@
|
|||
import {Type, isArray, isPresent} from "angular2/src/facade/lang";
|
||||
import {List, ListWrapper, Map, StringMapWrapper, MapWrapper} from "angular2/src/facade/collection";
|
||||
import {
|
||||
ProtoViewDto,
|
||||
DirectiveMetadata,
|
||||
ElementBinder,
|
||||
DirectiveBinder,
|
||||
ElementPropertyBinding,
|
||||
EventBinding,
|
||||
ViewDefinition
|
||||
} from "angular2/src/render/api";
|
||||
import {AST, ASTWithSource} from "angular2/change_detection";
|
||||
import {Parser} from "angular2/src/change_detection/parser/parser";
|
||||
|
||||
export class Serializer {
|
||||
static parser: Parser = null;
|
||||
|
||||
static serialize(obj: any, type: Type): Object {
|
||||
if (!isPresent(obj)) {
|
||||
return null;
|
||||
}
|
||||
if (isArray(obj)) {
|
||||
var serializedObj = [];
|
||||
ListWrapper.forEach(obj, (val) => { serializedObj.push(Serializer.serialize(val, type)); });
|
||||
return serializedObj;
|
||||
}
|
||||
if (type == ViewDefinition) {
|
||||
return ViewDefinitionSerializer.serialize(obj);
|
||||
} else if (type == DirectiveBinder) {
|
||||
return DirectiveBinderSerializer.serialize(obj);
|
||||
} else if (type == ProtoViewDto) {
|
||||
return ProtoViewDtoSerializer.serialize(obj);
|
||||
} else if (type == ElementBinder) {
|
||||
return ElementBinderSerializer.serialize(obj);
|
||||
} else if (type == DirectiveMetadata) {
|
||||
return DirectiveMetadataSerializer.serialize(obj);
|
||||
} else if (type == ASTWithSource) {
|
||||
return ASTWithSourceSerializer.serialize(obj);
|
||||
} else {
|
||||
throw "No serializer for " + type.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: template this to return the type that is passed if possible
|
||||
static deserialize(map, type: Type, data?): any {
|
||||
if (!isPresent(map)) {
|
||||
return null;
|
||||
}
|
||||
if (isArray(map)) {
|
||||
var obj: List<any> = new List<any>();
|
||||
ListWrapper.forEach(map, (val) => { obj.push(Serializer.deserialize(val, type, data)); });
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (type == ViewDefinition) {
|
||||
return ViewDefinitionSerializer.deserialize(map);
|
||||
} else if (type == DirectiveBinder) {
|
||||
return DirectiveBinderSerializer.deserialize(map);
|
||||
} else if (type == ProtoViewDto) {
|
||||
return ProtoViewDtoSerializer.deserialize(map);
|
||||
} else if (type == DirectiveMetadata) {
|
||||
return DirectiveMetadataSerializer.deserialize(map);
|
||||
} else if (type == ElementBinder) {
|
||||
return ElementBinderSerializer.deserialize(map);
|
||||
} else if (type == ASTWithSource) {
|
||||
return ASTWithSourceSerializer.deserialize(map, data);
|
||||
} else {
|
||||
throw "No deserializer for " + type.toString();
|
||||
}
|
||||
}
|
||||
|
||||
static mapToObject(map, type?: Type): Object {
|
||||
var object = {};
|
||||
var serialize = isPresent(type);
|
||||
|
||||
MapWrapper.forEach(map, (value, key) => {
|
||||
if (serialize) {
|
||||
object[key] = Serializer.serialize(value, type);
|
||||
} else {
|
||||
object[key] = value;
|
||||
}
|
||||
});
|
||||
return object;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transforms a Javascript object into a Map<string, V>
|
||||
* If the values need to be deserialized pass in their type
|
||||
* and they will be deserialized before being placed in the map
|
||||
*/
|
||||
static objectToMap(obj, type?: Type, data?): Map<string, any> {
|
||||
if (isPresent(type)) {
|
||||
var map: Map<string, any> = new Map();
|
||||
StringMapWrapper.forEach(
|
||||
obj, (key, val) => { map.set(key, Serializer.deserialize(val, type, data)); });
|
||||
return map;
|
||||
} else {
|
||||
return MapWrapper.createFromStringMap(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ASTWithSourceSerializer {
|
||||
static serialize(tree: ASTWithSource): Object {
|
||||
return { 'input': tree.source, 'location': tree.location }
|
||||
}
|
||||
|
||||
static deserialize(obj: any, data: string): AST {
|
||||
// TODO: make ASTs serializable
|
||||
var ast: AST;
|
||||
switch (data) {
|
||||
case "interpolation":
|
||||
ast = Serializer.parser.parseInterpolation(obj.input, obj.location);
|
||||
break;
|
||||
case "binding":
|
||||
ast = Serializer.parser.parseBinding(obj.input, obj.location);
|
||||
break;
|
||||
case "simpleBinding":
|
||||
ast = Serializer.parser.parseSimpleBinding(obj.input, obj.location);
|
||||
break;
|
||||
/*case "templateBindings":
|
||||
ast = Serializer.parser.parseTemplateBindings(obj.input, obj.location);
|
||||
break;*/
|
||||
case "interpolation":
|
||||
ast = Serializer.parser.parseInterpolation(obj.input, obj.location);
|
||||
break;
|
||||
default:
|
||||
throw "No AST deserializer for " + data;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
}
|
||||
|
||||
class ViewDefinitionSerializer {
|
||||
static serialize(view: ViewDefinition): Object {
|
||||
return {
|
||||
'componentId': view.componentId,
|
||||
'templateAbsUrl': view.templateAbsUrl,
|
||||
'template': view.template,
|
||||
'directives': Serializer.serialize(view.directives, DirectiveMetadata),
|
||||
'styleAbsUrls': view.styleAbsUrls,
|
||||
'styles': view.styles
|
||||
};
|
||||
}
|
||||
static deserialize(obj): ViewDefinition {
|
||||
return new ViewDefinition({
|
||||
componentId: obj.componentId,
|
||||
templateAbsUrl: obj.templateAbsUrl, template: obj.template,
|
||||
directives: Serializer.deserialize(obj.directives, DirectiveMetadata),
|
||||
styleAbsUrls: obj.styleAbsUrls,
|
||||
styles: obj.styles
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DirectiveBinderSerializer {
|
||||
static serialize(binder: DirectiveBinder): Object {
|
||||
return {
|
||||
'directiveIndex': binder.directiveIndex,
|
||||
'propertyBindings': Serializer.mapToObject(binder.propertyBindings, ASTWithSource),
|
||||
'eventBindings': Serializer.serialize(binder.eventBindings, EventBinding),
|
||||
'hostPropertyBindings':
|
||||
Serializer.serialize(binder.hostPropertyBindings, ElementPropertyBinding)
|
||||
};
|
||||
}
|
||||
|
||||
static deserialize(obj): DirectiveBinder {
|
||||
return new DirectiveBinder({
|
||||
directiveIndex: obj.directiveIndex,
|
||||
propertyBindings: Serializer.objectToMap(obj.propertyBindings, ASTWithSource, "binding"),
|
||||
eventBindings: Serializer.deserialize(obj.eventBindings, EventBinding),
|
||||
hostPropertyBindings: Serializer.deserialize(obj.hostPropertyBindings, ElementPropertyBinding)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ElementBinderSerializer {
|
||||
static serialize(binder: ElementBinder): Object {
|
||||
return {
|
||||
'index': binder.index, 'parentIndex': binder.parentIndex,
|
||||
'distanceToParent': binder.distanceToParent,
|
||||
'directives': Serializer.serialize(binder.directives, DirectiveBinder),
|
||||
'nestedProtoView': Serializer.serialize(binder.nestedProtoView, ProtoViewDto),
|
||||
'propertyBindings': Serializer.serialize(binder.propertyBindings, ElementPropertyBinding),
|
||||
'variableBindings': Serializer.mapToObject(binder.variableBindings),
|
||||
'eventBindings': Serializer.serialize(binder.eventBindings, EventBinding),
|
||||
'textBindings': Serializer.serialize(binder.textBindings, ASTWithSource),
|
||||
'readAttributes': Serializer.mapToObject(binder.readAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
static deserialize(obj): ElementBinder {
|
||||
return new ElementBinder({
|
||||
index: obj.index,
|
||||
parentIndex: obj.parentIndex,
|
||||
distanceToParent: obj.distanceToParent,
|
||||
directives: Serializer.deserialize(obj.directives, DirectiveBinder),
|
||||
nestedProtoView: Serializer.deserialize(obj.nestedProtoView, ProtoViewDto),
|
||||
propertyBindings: Serializer.deserialize(obj.propertyBindings, ElementPropertyBinding),
|
||||
variableBindings: Serializer.objectToMap(obj.variableBindings),
|
||||
eventBindings: Serializer.deserialize(obj.eventBindings, EventBinding),
|
||||
textBindings: Serializer.deserialize(obj.textBindings, ASTWithSource, "interpolation"),
|
||||
readAttributes: Serializer.objectToMap(obj.readAttributes)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ProtoViewDtoSerializer {
|
||||
static serialize(view: ProtoViewDto): Object {
|
||||
// TODO: fix render refs and write a serializer for them
|
||||
return {
|
||||
'render': null, 'elementBinders': Serializer.serialize(view.elementBinders, ElementBinder),
|
||||
'variableBindings': Serializer.mapToObject(view.variableBindings), 'type': view.type
|
||||
}
|
||||
}
|
||||
|
||||
static deserialize(obj): ProtoViewDto {
|
||||
return new ProtoViewDto({
|
||||
render: null, // TODO: fix render refs and write a serializer for them
|
||||
elementBinders: Serializer.deserialize(obj.elementBinders, ElementBinder),
|
||||
variableBindings: Serializer.objectToMap(obj.variableBindings),
|
||||
type: obj.type
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DirectiveMetadataSerializer {
|
||||
static serialize(meta: DirectiveMetadata): Object {
|
||||
var obj = {
|
||||
'id': meta.id,
|
||||
'selector': meta.selector,
|
||||
'compileChildren': meta.compileChildren,
|
||||
'hostProperties': Serializer.mapToObject(meta.hostProperties),
|
||||
'hostListeners': Serializer.mapToObject(meta.hostListeners),
|
||||
'hostActions': Serializer.mapToObject(meta.hostActions),
|
||||
'hostAttributes': Serializer.mapToObject(meta.hostAttributes),
|
||||
'properties': meta.properties,
|
||||
'readAttributes': meta.readAttributes,
|
||||
'type': meta.type,
|
||||
'exportAs': meta.exportAs,
|
||||
'callOnDestroy': meta.callOnDestroy,
|
||||
'callOnCheck': meta.callOnCheck,
|
||||
'callOnInit': meta.callOnInit,
|
||||
'callOnAllChangesDone': meta.callOnAllChangesDone,
|
||||
'changeDetection': meta.changeDetection,
|
||||
'events': meta.events
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
static deserialize(obj): DirectiveMetadata {
|
||||
return new DirectiveMetadata({
|
||||
id: obj.id,
|
||||
selector: obj.selector,
|
||||
compileChildren: obj.compileChildren,
|
||||
hostProperties: Serializer.objectToMap(obj.hostProperties),
|
||||
hostListeners: Serializer.objectToMap(obj.hostListeners),
|
||||
hostActions: Serializer.objectToMap(obj.hostActions),
|
||||
hostAttributes: Serializer.objectToMap(obj.hostAttributes),
|
||||
properties: obj.properties,
|
||||
readAttributes: obj.readAttributes,
|
||||
type: obj.type,
|
||||
exportAs: obj.exportAs,
|
||||
callOnDestroy: obj.callOnDestroy,
|
||||
callOnCheck: obj.callOnCheck,
|
||||
callOnInit: obj.callOnInit,
|
||||
callOnAllChangesDone: obj.callOnAllChangesDone,
|
||||
changeDetection: obj.changeDetection,
|
||||
events: obj.events
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
import {Type, isArray, isPresent} from "angular2/src/facade/lang";
|
||||
import {List, ListWrapper, Map, StringMapWrapper, MapWrapper} from "angular2/src/facade/collection";
|
||||
import {
|
||||
ProtoViewDto,
|
||||
DirectiveMetadata,
|
||||
ElementBinder,
|
||||
DirectiveBinder,
|
||||
ElementPropertyBinding,
|
||||
EventBinding,
|
||||
ViewDefinition
|
||||
} from "angular2/src/render/api";
|
||||
import {AST, ASTWithSource} from "angular2/change_detection";
|
||||
import {Parser} from "angular2/src/change_detection/parser/parser";
|
||||
|
||||
export class Serializer {
|
||||
static parser: Parser = null;
|
||||
|
||||
static serialize(obj: any, type: Type): Object {
|
||||
if (!isPresent(obj)) {
|
||||
return null;
|
||||
}
|
||||
if (isArray(obj)) {
|
||||
var serializedObj = [];
|
||||
ListWrapper.forEach(obj, (val) => { serializedObj.push(Serializer.serialize(val, type)); });
|
||||
return serializedObj;
|
||||
}
|
||||
if (type == ViewDefinition) {
|
||||
return ViewDefinitionSerializer.serialize(obj);
|
||||
} else if (type == DirectiveBinder) {
|
||||
return DirectiveBinderSerializer.serialize(obj);
|
||||
} else if (type == ProtoViewDto) {
|
||||
return ProtoViewDtoSerializer.serialize(obj);
|
||||
} else if (type == ElementBinder) {
|
||||
return ElementBinderSerializer.serialize(obj);
|
||||
} else if (type == DirectiveMetadata) {
|
||||
return DirectiveMetadataSerializer.serialize(obj);
|
||||
} else if (type == ASTWithSource) {
|
||||
return ASTWithSourceSerializer.serialize(obj);
|
||||
} else {
|
||||
throw "No serializer for " + type.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: template this to return the type that is passed if possible
|
||||
static deserialize(map, type: Type, data?): any {
|
||||
if (!isPresent(map)) {
|
||||
return null;
|
||||
}
|
||||
if (isArray(map)) {
|
||||
var obj: List<any> = new List<any>();
|
||||
ListWrapper.forEach(map, (val) => { obj.push(Serializer.deserialize(val, type, data)); });
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (type == ViewDefinition) {
|
||||
return ViewDefinitionSerializer.deserialize(map);
|
||||
} else if (type == DirectiveBinder) {
|
||||
return DirectiveBinderSerializer.deserialize(map);
|
||||
} else if (type == ProtoViewDto) {
|
||||
return ProtoViewDtoSerializer.deserialize(map);
|
||||
} else if (type == DirectiveMetadata) {
|
||||
return DirectiveMetadataSerializer.deserialize(map);
|
||||
} else if (type == ElementBinder) {
|
||||
return ElementBinderSerializer.deserialize(map);
|
||||
} else if (type == ASTWithSource) {
|
||||
return ASTWithSourceSerializer.deserialize(map, data);
|
||||
} else {
|
||||
throw "No deserializer for " + type.toString();
|
||||
}
|
||||
}
|
||||
|
||||
static mapToObject(map, type?: Type): Object {
|
||||
var object = {};
|
||||
var serialize = isPresent(type);
|
||||
|
||||
MapWrapper.forEach(map, (value, key) => {
|
||||
if (serialize) {
|
||||
object[key] = Serializer.serialize(value, type);
|
||||
} else {
|
||||
object[key] = value;
|
||||
}
|
||||
});
|
||||
return object;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transforms a Javascript object into a Map<string, V>
|
||||
* If the values need to be deserialized pass in their type
|
||||
* and they will be deserialized before being placed in the map
|
||||
*/
|
||||
static objectToMap(obj, type?: Type, data?): Map<string, any> {
|
||||
if (isPresent(type)) {
|
||||
var map: Map<string, any> = new Map();
|
||||
StringMapWrapper.forEach(
|
||||
obj, (key, val) => { map.set(key, Serializer.deserialize(val, type, data)); });
|
||||
return map;
|
||||
} else {
|
||||
return MapWrapper.createFromStringMap(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ASTWithSourceSerializer {
|
||||
static serialize(tree: ASTWithSource): Object {
|
||||
return { 'input': tree.source, 'location': tree.location }
|
||||
}
|
||||
|
||||
static deserialize(obj: any, data: string): AST {
|
||||
// TODO: make ASTs serializable
|
||||
var ast: AST;
|
||||
switch (data) {
|
||||
case "interpolation":
|
||||
ast = Serializer.parser.parseInterpolation(obj.input, obj.location);
|
||||
break;
|
||||
case "binding":
|
||||
ast = Serializer.parser.parseBinding(obj.input, obj.location);
|
||||
break;
|
||||
case "simpleBinding":
|
||||
ast = Serializer.parser.parseSimpleBinding(obj.input, obj.location);
|
||||
break;
|
||||
/*case "templateBindings":
|
||||
ast = Serializer.parser.parseTemplateBindings(obj.input, obj.location);
|
||||
break;*/
|
||||
case "interpolation":
|
||||
ast = Serializer.parser.parseInterpolation(obj.input, obj.location);
|
||||
break;
|
||||
default:
|
||||
throw "No AST deserializer for " + data;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
}
|
||||
|
||||
class ViewDefinitionSerializer {
|
||||
static serialize(view: ViewDefinition): Object{
|
||||
return {
|
||||
'componentId': view.componentId,
|
||||
'templateAbsUrl': view.templateAbsUrl,
|
||||
'template': view.template,
|
||||
'directives': Serializer.serialize(view.directives, DirectiveMetadata),
|
||||
'styleAbsUrls': view.styleAbsUrls,
|
||||
'styles': view.styles
|
||||
};
|
||||
}
|
||||
static deserialize(obj): ViewDefinition {
|
||||
return new ViewDefinition({
|
||||
'componentId': obj.componentId,
|
||||
'templateAbsUrl': obj.templateAbsUrl,
|
||||
'template': obj.template,
|
||||
'directives': Serializer.deserialize(obj.directives, DirectiveMetadata),
|
||||
'styleAbsUrls': obj.styleAbsUrls,
|
||||
'styles': obj.styles
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DirectiveBinderSerializer {
|
||||
static serialize(binder: DirectiveBinder): Object {
|
||||
return {
|
||||
'directiveIndex': binder.directiveIndex,
|
||||
'propertyBindings': Serializer.mapToObject(binder.propertyBindings, ASTWithSource),
|
||||
'eventBindings': Serializer.serialize(binder.eventBindings, EventBinding),
|
||||
'hostPropertyBindings':
|
||||
Serializer.serialize(binder.hostPropertyBindings, ElementPropertyBinding)
|
||||
};
|
||||
}
|
||||
|
||||
static deserialize(obj): DirectiveBinder {
|
||||
return new DirectiveBinder({
|
||||
'directiveIndex': obj.directiveIndex,
|
||||
'propertyBindings': Serializer.objectToMap(obj.propertyBindings, ASTWithSource, "binding"),
|
||||
'eventBindings': Serializer.deserialize(obj.eventBindings, EventBinding),
|
||||
'hostPropertyBindings':
|
||||
Serializer.deserialize(obj.hostPropertyBindings, ElementPropertyBinding)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ElementBinderSerializer {
|
||||
static serialize(binder: ElementBinder): Object {
|
||||
return {
|
||||
'index': binder.index,
|
||||
'parentIndex': binder.parentIndex,
|
||||
'distanceToParent': binder.distanceToParent,
|
||||
'directives': Serializer.serialize(binder.directives, DirectiveBinder),
|
||||
'nestedProtoView': Serializer.serialize(binder.nestedProtoView, ProtoViewDto),
|
||||
'propertyBindings': Serializer.serialize(binder.propertyBindings, ElementPropertyBinding),
|
||||
'variableBindings': Serializer.mapToObject(binder.variableBindings),
|
||||
'eventBindings': Serializer.serialize(binder.eventBindings, EventBinding),
|
||||
'textBindings': Serializer.serialize(binder.textBindings, ASTWithSource),
|
||||
'readAttributes': Serializer.mapToObject(binder.readAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
static deserialize(obj): ElementBinder {
|
||||
return new ElementBinder({
|
||||
'index': obj.index,
|
||||
'parentIndex': obj.parentIndex,
|
||||
'distanceToParent': obj.distanceToParent,
|
||||
'directives': Serializer.deserialize(obj.directives, DirectiveBinder),
|
||||
'nestedProtoView': Serializer.deserialize(obj.nestedProtoView, ProtoViewDto),
|
||||
'propertyBindings': Serializer.deserialize(obj.propertyBindings, ElementPropertyBinding),
|
||||
'variableBindings': Serializer.objectToMap(obj.variableBindings),
|
||||
'eventBindings': Serializer.deserialize(obj.eventBindings, EventBinding),
|
||||
'textBindings': Serializer.deserialize(obj.textBindings, ASTWithSource, "interpolation"),
|
||||
'readAttributes': Serializer.objectToMap(obj.readAttributes)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ProtoViewDtoSerializer {
|
||||
static serialize(view: ProtoViewDto): Object {
|
||||
return {
|
||||
'render': null, // TODO: fix render refs and write a serializer for them
|
||||
'elementBinders': Serializer.serialize(view.elementBinders, ElementBinder),
|
||||
'variableBindings': Serializer.mapToObject(view.variableBindings),
|
||||
'type': view.type
|
||||
}
|
||||
}
|
||||
|
||||
static deserialize(obj): ProtoViewDto {
|
||||
return new ProtoViewDto({
|
||||
'render': null, // TODO: fix render refs and write a serializer for them
|
||||
'elementBinders': Serializer.deserialize(obj.elementBinders, ElementBinder),
|
||||
'variableBindings': Serializer.objectToMap(obj.variableBindings),
|
||||
'type': obj.type
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DirectiveMetadataSerializer {
|
||||
static serialize(meta: DirectiveMetadata): Object {
|
||||
var obj = {
|
||||
'id': meta.id,
|
||||
'selector': meta.selector,
|
||||
'compileChildren': meta.compileChildren,
|
||||
'hostProperties': Serializer.mapToObject(meta.hostProperties),
|
||||
'hostListeners': Serializer.mapToObject(meta.hostListeners),
|
||||
'hostActions': Serializer.mapToObject(meta.hostActions),
|
||||
'hostAttributes': Serializer.mapToObject(meta.hostAttributes),
|
||||
'properties': meta.properties,
|
||||
'readAttributes': meta.readAttributes,
|
||||
'type': meta.type,
|
||||
'exportAs': meta.exportAs,
|
||||
'callOnDestroy': meta.callOnDestroy,
|
||||
'callOnCheck': meta.callOnCheck,
|
||||
'callOnInit': meta.callOnInit,
|
||||
'callOnAllChangesDone': meta.callOnAllChangesDone,
|
||||
'changeDetection': meta.changeDetection,
|
||||
'events': meta.events
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
static deserialize(obj): DirectiveMetadata {
|
||||
return new DirectiveMetadata({
|
||||
'id': obj.id,
|
||||
'selector': obj.selector,
|
||||
'compileChildren': obj.compileChildren,
|
||||
'hostProperties': Serializer.objectToMap(obj.hostProperties),
|
||||
'hostListeners': Serializer.objectToMap(obj.hostListeners),
|
||||
'hostActions': Serializer.objectToMap(obj.hostActions),
|
||||
'hostAttributes': Serializer.objectToMap(obj.hostAttributes),
|
||||
'properties': obj.properties,
|
||||
'readAttributes': obj.readAttributes,
|
||||
'type': obj.type,
|
||||
'exportAs': obj.exportAs,
|
||||
'callOnDestroy': obj.callOnDestroy,
|
||||
'callOnCheck': obj.callOnCheck,
|
||||
'callOnInit': obj.callOnInit,
|
||||
'callOnAllChangesDone': obj.callOnAllChangesDone,
|
||||
'changeDetection': obj.changeDetection,
|
||||
'events': obj.events
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
library angular2.src.web_workers.ui;
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
import "package:angular2/src/web-workers/shared/message_bus.dart"
|
||||
show MessageBus, MessageBusSink, MessageBusSource;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void bootstrap(String uri) {
|
||||
throw "Not Implemented";
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from the main thread to spawn and communicate with the worker thread
|
||||
*/
|
||||
Future<UIMessageBus> spawnWorker(Uri uri) {
|
||||
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 UIMessageBusSink(sendPort);
|
||||
return new UIMessageBus(sink, source);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class UIMessageBus extends MessageBus {
|
||||
final UIMessageBusSink sink;
|
||||
final UIMessageBusSource source;
|
||||
|
||||
UIMessageBus(UIMessageBusSink sink, UIMessageBusSource source)
|
||||
: sink = sink,
|
||||
source = source;
|
||||
}
|
||||
|
||||
class UIMessageBusSink extends MessageBusSink {
|
||||
final SendPort _port;
|
||||
|
||||
UIMessageBusSink(SendPort port) : _port = port;
|
||||
|
||||
void send(message) {
|
||||
_port.send(message);
|
||||
}
|
||||
}
|
||||
|
||||
class UIMessageBusSource extends MessageBusSource {
|
||||
final ReceivePort _port;
|
||||
final Stream rawDataStream;
|
||||
|
||||
UIMessageBusSource(ReceivePort port)
|
||||
: _port = port,
|
||||
rawDataStream = port.asBroadcastStream();
|
||||
|
||||
Future<SendPort> get sink => rawDataStream.firstWhere((message) {
|
||||
return message is SendPort;
|
||||
});
|
||||
|
||||
void listen(Function fn) {
|
||||
rawDataStream.listen((message) {
|
||||
fn({"data": message});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import {
|
||||
MessageBus,
|
||||
MessageBusSource,
|
||||
MessageBusSink,
|
||||
SourceListener
|
||||
} from "angular2/src/web-workers/shared/message_bus";
|
||||
import {BaseException} from "angular2/src/facade/lang";
|
||||
|
||||
/**
|
||||
* 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): void {
|
||||
throw new BaseException("Not Implemented");
|
||||
}
|
||||
|
||||
export function spawnWorker(uri: string): MessageBus {
|
||||
var worker: Worker = new Worker(uri);
|
||||
return new UIMessageBus(new UIMessageBusSink(worker), new UIMessageBusSource(worker));
|
||||
}
|
||||
|
||||
export class UIMessageBus implements MessageBus {
|
||||
constructor(public sink: UIMessageBusSink, public source: UIMessageBusSource) {}
|
||||
}
|
||||
|
||||
export class UIMessageBusSink implements MessageBusSink {
|
||||
constructor(private _worker: Worker) {}
|
||||
|
||||
send(message: Object): void { this._worker.postMessage(message); }
|
||||
}
|
||||
|
||||
export class UIMessageBusSource implements MessageBusSource {
|
||||
constructor(private _worker: Worker) {}
|
||||
|
||||
listen(fn: SourceListener): void { this._worker.addEventListener("message", fn); }
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
library angular2.src.web_workers.worker;
|
||||
|
||||
import "package:angular2/src/web-workers/shared/message_bus.dart"
|
||||
show MessageBus, MessageBusSource, MessageBusSink;
|
||||
import "package:angular2/src/facade/async.dart" show Future;
|
||||
import "package:angular2/src/core/application.dart" show ApplicationRef;
|
||||
import "package:angular2/src/facade/lang.dart" show Type, BaseException;
|
||||
import "dart:isolate";
|
||||
import "dart:async";
|
||||
|
||||
/**
|
||||
* 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<ApplicationRef> bootstrapWebworker(
|
||||
SendPort replyTo, Type appComponentType,
|
||||
[List<dynamic> componentInjectableBindings = null,
|
||||
Function errorReporter = null]) {
|
||||
throw new BaseException("Not implemented");
|
||||
}
|
||||
|
||||
class WorkerMessageBus extends MessageBus {
|
||||
final WorkerMessageBusSink sink;
|
||||
final WorkerMessageBusSource source;
|
||||
|
||||
WorkerMessageBus(this.sink, this.source);
|
||||
|
||||
WorkerMessageBus.fromPorts(SendPort sPort, ReceivePort rPort)
|
||||
: sink = new WorkerMessageBusSink(sPort, rPort),
|
||||
source = new WorkerMessageBusSource(rPort);
|
||||
}
|
||||
|
||||
class WorkerMessageBusSink extends MessageBusSink {
|
||||
final SendPort _port;
|
||||
|
||||
WorkerMessageBusSink(SendPort sPort, ReceivePort rPort) : _port = sPort {
|
||||
this.send(rPort.sendPort);
|
||||
}
|
||||
|
||||
void send(dynamic message) {
|
||||
this._port.send(message);
|
||||
}
|
||||
}
|
||||
|
||||
class WorkerMessageBusSource extends MessageBusSource {
|
||||
final ReceivePort _port;
|
||||
final Stream rawDataStream;
|
||||
|
||||
WorkerMessageBusSource(ReceivePort rPort)
|
||||
: _port = rPort,
|
||||
rawDataStream = rPort.asBroadcastStream();
|
||||
|
||||
void listen(Function fn) {
|
||||
rawDataStream.listen((message) {
|
||||
fn({"data": message});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import {
|
||||
MessageBus,
|
||||
MessageBusSource,
|
||||
MessageBusSink,
|
||||
SourceListener
|
||||
} from "angular2/src/web-workers/shared/message_bus";
|
||||
import {Type, BaseException} from "angular2/src/facade/lang";
|
||||
import {Binding} from "angular2/di";
|
||||
|
||||
import {ApplicationRef} from "angular2/src/core/application";
|
||||
|
||||
/**
|
||||
* 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, componentInjectableBindings: List<Type | Binding | List<any>> = null,
|
||||
errorReporter: Function = null): Promise<ApplicationRef> {
|
||||
throw new BaseException("Not Implemented");
|
||||
}
|
||||
|
||||
export class WorkerMessageBus implements MessageBus {
|
||||
sink: WorkerMessageBusSink;
|
||||
source: WorkerMessageBusSource;
|
||||
|
||||
constructor(sink: WorkerMessageBusSink, source: WorkerMessageBusSource) {
|
||||
this.sink = sink;
|
||||
this.source = source;
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkerMessageBusSink implements MessageBusSink {
|
||||
public send(message: Object) { postMessage(message, null); }
|
||||
}
|
||||
|
||||
export class WorkerMessageBusSource implements MessageBusSource {
|
||||
public listen(fn: SourceListener) { addEventListener("message", fn); }
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/// <reference path="../../../globals.d.ts" />
|
||||
import {MessageBus} from "angular2/src/web-workers/shared/message_bus";
|
||||
import {print, isPresent, DateWrapper, stringify} from "../../facade/lang";
|
||||
import {Promise, PromiseCompleter, PromiseWrapper} from "angular2/src/facade/async";
|
||||
import {ListWrapper, StringMapWrapper, MapWrapper} from "../../facade/collection";
|
||||
import {Serializer} from "angular2/src/web-workers/shared/serializer";
|
||||
|
||||
export class MessageBroker {
|
||||
private _pending: Map<string, Function> = new Map<string, Function>();
|
||||
|
||||
constructor(private _messageBus: MessageBus) {
|
||||
this._messageBus.source.listen((data) => this._handleMessage(data['data']));
|
||||
}
|
||||
|
||||
private _generateMessageId(name: string): string {
|
||||
var time: string = stringify(DateWrapper.toMillis(DateWrapper.now()));
|
||||
var iteration: number = 0;
|
||||
var id: string = name + time + stringify(iteration);
|
||||
while (isPresent(this._pending[id])) {
|
||||
id = `${name}${time}${iteration}`;
|
||||
iteration++;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
runOnUiThread(args: UiArguments): Promise<any> {
|
||||
var completer = PromiseWrapper.completer();
|
||||
var id: string = this._generateMessageId(args.type + args.method);
|
||||
this._pending.set(id, completer.resolve);
|
||||
PromiseWrapper.catchError(completer.promise, (err, stack?) => {
|
||||
print(err);
|
||||
completer.reject(err, stack);
|
||||
});
|
||||
|
||||
var fnArgs = [];
|
||||
if (isPresent(args.args)) {
|
||||
ListWrapper.forEach(args.args, (argument) => {
|
||||
fnArgs.push(Serializer.serialize(argument.value, argument.type));
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): Create a class for these messages so we don't keep using StringMap
|
||||
var message = {'type': args.type, 'method': args.method, 'args': fnArgs, 'id': id};
|
||||
this._messageBus.sink.send(message);
|
||||
return completer.promise;
|
||||
}
|
||||
|
||||
private _handleMessage(message: StringMap<string, any>): void {
|
||||
var data = new MessageData(message);
|
||||
// TODO(jteplitz602): replace these strings with messaging constants
|
||||
var id = data.value.id;
|
||||
if (this._pending.has(id)) {
|
||||
this._pending.get(id)(data.value);
|
||||
this._pending.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MessageData {
|
||||
type: string;
|
||||
value: MessageResult;
|
||||
|
||||
constructor(data: StringMap<string, any>) {
|
||||
this.type = StringMapWrapper.get(data, "type");
|
||||
if (StringMapWrapper.contains(data, "value")) {
|
||||
this.value = new MessageResult(StringMapWrapper.get(data, "value"));
|
||||
} else {
|
||||
this.value = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MessageResult {
|
||||
id: string;
|
||||
value: any;
|
||||
|
||||
constructor(result: StringMap<string, any>) {
|
||||
this.id = StringMapWrapper.get(result, "id");
|
||||
this.value = StringMapWrapper.get(result, "value");
|
||||
}
|
||||
}
|
||||
|
||||
export class FnArg {
|
||||
constructor(public value, public type) {}
|
||||
}
|
||||
|
||||
export class UiArguments {
|
||||
constructor(public type: string, public method: string, public args?: List<FnArg>) {}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
library examples.e2e_test.message_bus;
|
||||
|
||||
main() {
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import {verifyNoBrowserErrors} from 'angular2/src/test_lib/e2e_util';
|
||||
import {PromiseWrapper} from "angular2/src/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);
|
||||
|
||||
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()');
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,25 @@
|
|||
library angular2.examples.message_broker.background_index;
|
||||
|
||||
import "package:angular2/src/web-workers/worker/application.dart"
|
||||
show WorkerMessageBus, WorkerMessageBusSource, WorkerMessageBusSink;
|
||||
import "package:angular2/src/web-workers/worker/broker.dart"
|
||||
show MessageBroker, UiArguments;
|
||||
|
||||
import "dart:isolate";
|
||||
|
||||
main(List<String> args, SendPort replyTo) {
|
||||
ReceivePort rPort = new ReceivePort();
|
||||
WorkerMessageBus bus = new WorkerMessageBus.fromPorts(replyTo, rPort);
|
||||
bus.source.listen((message) {
|
||||
if (identical(message['data']['type'], "echo")) {
|
||||
bus.sink
|
||||
.send({"type": "echo_response", "value": message['data']['value']});
|
||||
}
|
||||
});
|
||||
|
||||
MessageBroker broker = new MessageBroker(bus);
|
||||
var args = new UiArguments("test", "tester");
|
||||
broker.runOnUiThread(args).then((data) {
|
||||
bus.sink.send({"type": "result", "value": data.value});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import {
|
||||
WorkerMessageBus,
|
||||
WorkerMessageBusSource,
|
||||
WorkerMessageBusSink
|
||||
} from "angular2/src/web-workers/worker/application";
|
||||
import {MessageBroker, UiArguments} from "angular2/src/web-workers/worker/broker";
|
||||
|
||||
export function main() {
|
||||
var bus = new WorkerMessageBus(new WorkerMessageBusSink(), new WorkerMessageBusSource());
|
||||
bus.source.listen((message) => {
|
||||
if (message.data.type === "echo") {
|
||||
bus.sink.send({type: "echo_response", 'value': message.data.value});
|
||||
}
|
||||
});
|
||||
|
||||
var broker = new MessageBroker(bus);
|
||||
var args = new UiArguments("test", "tester");
|
||||
broker.runOnUiThread(args)
|
||||
.then((data) => { bus.sink.send({type: "result", value: data.value}); });
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
library angular2.examples.message_broker.index;
|
||||
|
||||
import "package:angular2/src/web-workers/ui/application.dart"
|
||||
show spawnWorker, UIMessageBus, UIMessageBusSink, UIMessageBusSource;
|
||||
|
||||
import "dart:html";
|
||||
|
||||
main() {
|
||||
var VALUE = 5;
|
||||
spawnWorker(Uri.parse("background_index.dart")).then((bus) {
|
||||
querySelector("#send_echo").addEventListener("click", (e) {
|
||||
var val = (querySelector("#echo_input") as InputElement).value;
|
||||
bus.sink.send({'type': 'echo', 'value': val});
|
||||
});
|
||||
bus.source.listen((message) {
|
||||
var data = message['data'];
|
||||
if (identical(data['type'], "echo_response")) {
|
||||
querySelector("#echo_result")
|
||||
.appendHtml("<span class='response'>${data['value']}</span>");
|
||||
} else if (identical(data['type'], "test")) {
|
||||
bus.sink.send(
|
||||
{'type': "result", 'value': {'id': data['id'], 'value': VALUE}});
|
||||
} else if (identical(data['type'], "result")) {
|
||||
querySelector("#ui_result")
|
||||
.appendHtml("<span class='result'>${data['value']}</span>");
|
||||
} else if (identical(data['type'], "ready")) {
|
||||
bus.sink.send({'type': "init"});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<title>Message Broker Example</title>
|
||||
<body>
|
||||
<input type="text" id="echo_input" />
|
||||
<button type="button" id="send_echo">Send Echo</button>
|
||||
<p id="echo_result"></p>
|
||||
<p id="ui_result"></p>
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
import {
|
||||
UIMessageBus,
|
||||
UIMessageBusSink,
|
||||
UIMessageBusSource
|
||||
} from "angular2/src/web-workers/ui/application";
|
||||
|
||||
var worker = new Worker("loader.js");
|
||||
var bus = new UIMessageBus(new UIMessageBusSink(worker), new UIMessageBusSource(worker));
|
||||
var VALUE = 5;
|
||||
|
||||
document.getElementById("send_echo")
|
||||
.addEventListener("click", (e) => {
|
||||
var val = (<HTMLInputElement>document.getElementById("echo_input")).value;
|
||||
bus.sink.send({type: "echo", value: val});
|
||||
});
|
||||
bus.source.listen((message) => {
|
||||
if (message.data.type === "echo_response") {
|
||||
document.getElementById("echo_result").innerHTML =
|
||||
`<span class='response'>${message.data.value}</span>`;
|
||||
} else if (message.data.type === "test") {
|
||||
bus.sink.send({type: "result", value: {id: message.data.id, value: VALUE}});
|
||||
} else if (message.data.type == "result") {
|
||||
document.getElementById("ui_result").innerHTML =
|
||||
`<span class='result'>${message.data.value}</span>`;
|
||||
} else if (message.data.type == "ready") {
|
||||
bus.sink.send({type: "init"});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
$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.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);
|
||||
});
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
importScripts("traceur-runtime.js",
|
||||
"es6-module-loader-sans-promises.src.js",
|
||||
"system.src.js",
|
||||
"extension-register.js",
|
||||
"extension-cjs.js",
|
||||
"Reflect.js",
|
||||
"runtime_paths.js");
|
|
@ -0,0 +1,11 @@
|
|||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = readJs;
|
||||
function readJs(file) {
|
||||
var content =
|
||||
fs.readFileSync(path.join('tools/broccoli/js-replace', file + '.js'), {encoding: 'utf-8'});
|
||||
// TODO(broccoli): we don't really need this, it's here to make the output match the
|
||||
// tools/build/html
|
||||
return content.substring(0, content.lastIndexOf("\n"));
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
var Funnel = require('broccoli-funnel');
|
||||
var htmlReplace = require('../html-replace');
|
||||
var jsReplace = require("../js-replace");
|
||||
var path = require('path');
|
||||
var stew = require('broccoli-stew');
|
||||
|
||||
|
@ -57,7 +58,8 @@ const kServedPaths = [
|
|||
'examples/src/material/input',
|
||||
'examples/src/material/progress-linear',
|
||||
'examples/src/material/radio',
|
||||
'examples/src/material/switcher'
|
||||
'examples/src/material/switcher',
|
||||
'examples/src/message_broker'
|
||||
];
|
||||
|
||||
|
||||
|
@ -66,27 +68,22 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||
'modules',
|
||||
{include: ['**/**'], exclude: ['**/*.cjs', 'benchmarks/e2e_test/**'], destDir: '/'});
|
||||
|
||||
// Use Traceur to transpile *.js sources to ES6
|
||||
var traceurTree = transpileWithTraceur(modulesTree, {
|
||||
destExtension: '.js',
|
||||
destSourceMapExtension: '.map',
|
||||
traceurOptions: {
|
||||
sourceMaps: true,
|
||||
annotations: true, // parse annotations
|
||||
types: true, // parse types
|
||||
script: false, // parse as a module
|
||||
memberVariables: true, // parse class fields
|
||||
modules: 'instantiate',
|
||||
// typeAssertionModule: 'rtts_assert/rtts_assert',
|
||||
// typeAssertions: options.typeAssertions,
|
||||
outputLanguage: 'es6'
|
||||
var scriptPathPatternReplacement = {
|
||||
match: '@@FILENAME_NO_EXT',
|
||||
replacement: function(replacement, relativePath) {
|
||||
return relativePath.replace(/\.\w+$/, '').replace(/\\/g, '/');
|
||||
}
|
||||
};
|
||||
|
||||
modulesTree = replace(modulesTree, {
|
||||
files: ["examples*/**/*.js"],
|
||||
patterns: [{match: /\$SCRIPTS\$/, replacement: jsReplace('SCRIPTS')}]
|
||||
});
|
||||
|
||||
// Use TypeScript to transpile the *.ts files to ES6
|
||||
// We don't care about errors: we let the TypeScript compilation to ES5
|
||||
// in node_tree.ts do the type-checking.
|
||||
var typescriptTree = compileWithTypescript(modulesTree, {
|
||||
var es6Tree = compileWithTypescript(modulesTree, {
|
||||
allowNonTsExtensions: false,
|
||||
declaration: true,
|
||||
emitDecoratorMetadata: true,
|
||||
|
@ -98,8 +95,6 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||
target: 'ES6'
|
||||
});
|
||||
|
||||
var es6Tree = mergeTrees([traceurTree, typescriptTree]);
|
||||
|
||||
// Call Traceur again to lower the ES6 build tree to ES5
|
||||
var es5Tree = transpileWithTraceur(es6Tree, {
|
||||
destExtension: '.js',
|
||||
|
@ -113,7 +108,6 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||
es6Tree = mergeTrees([es6Tree, extras]);
|
||||
});
|
||||
|
||||
|
||||
var vendorScriptsTree = flatten(new Funnel('.', {
|
||||
files: [
|
||||
'node_modules/zone.js/dist/zone-microtask.js',
|
||||
|
@ -148,22 +142,16 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||
return funnels;
|
||||
}
|
||||
|
||||
var scriptPathPatternReplacement = {
|
||||
match: '@@FILENAME_NO_EXT',
|
||||
replacement: function(replacement, relativePath) {
|
||||
return relativePath.replace(/\.\w+$/, '').replace(/\\/g, '/');
|
||||
}
|
||||
};
|
||||
|
||||
var htmlTree = new Funnel(modulesTree, {include: ['*/src/**/*.html'], destDir: '/'});
|
||||
htmlTree = replace(htmlTree, {
|
||||
files: ['examples*/**'],
|
||||
files: ['examples*/**/*.html'],
|
||||
patterns: [
|
||||
{match: /\$SCRIPTS\$/, replacement: htmlReplace('SCRIPTS')},
|
||||
scriptPathPatternReplacement
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
htmlTree = replace(htmlTree, {
|
||||
files: ['benchmarks/**'],
|
||||
patterns: [
|
||||
|
|
Loading…
Reference in New Issue