├── dist └── tags │ └── tags.json ├── .jshintrc ├── .npmignore ├── gulpfile.js ├── jsconfig.json ├── app ├── benchmark-resources │ ├── content-selectors.js │ ├── point.html │ ├── surrogate-behaviors.html │ ├── point.js │ ├── template-parts.html │ ├── template-parts.js │ ├── content-selectors.html │ ├── index.js │ ├── surrogate-behaviors.js │ └── attributes.js ├── benchmarking │ ├── type.js │ ├── definition.js │ ├── result-factory.js │ ├── definition-repository.js │ ├── macro-runner.js │ ├── coordinator.js │ ├── micro-runner.js │ └── result-repository.js ├── resources │ ├── skip-value-converter.js │ ├── take-value-converter.js │ └── index.js ├── util │ ├── user-agent.js │ └── parse-json.js ├── ui │ ├── harness │ │ ├── result-set.html │ │ ├── result-set.js │ │ ├── harness.js │ │ └── harness.html │ ├── app.html │ ├── app.js │ ├── tags │ │ ├── chart.js │ │ ├── tags.html │ │ └── tags.js │ └── benchmark-view-model.js ├── styles.css ├── index.html └── main.js ├── .gitignore ├── benchmarks ├── micro │ ├── templating-compile-vanilla │ │ └── index.js │ ├── templating-create-vanilla │ │ └── index.js │ ├── di-singleton │ │ └── index.js │ ├── di-transient │ │ └── index.js │ ├── templating-compile-and-create-vanilla │ │ └── index.js │ ├── templating-create-with-bindings │ │ └── index.js │ ├── templating-compile-and-create-with-bindings │ │ └── index.js │ ├── templating-compile-template-parts │ │ └── index.js │ ├── templating-compile-with-behaviors │ │ └── index.js │ ├── templating-compile-with-bindings │ │ └── index.js │ ├── templating-create-template-parts │ │ └── index.js │ ├── templating-create-with-behaviors │ │ └── index.js │ ├── di-singleton-parent │ │ └── index.js │ ├── di-singleton-parent4 │ │ └── index.js │ ├── di-transient-parent │ │ └── index.js │ ├── di-transient-parent4 │ │ └── index.js │ ├── templating-compile-and-create-template-parts │ │ └── index.js │ ├── templating-compile-and-create-with-behaviors │ │ └── index.js │ ├── templating-compile-content-selectors │ │ └── index.js │ ├── templating-create-content-selectors │ │ └── index.js │ ├── di-auto-registration-sans-metadata │ │ └── index.js │ ├── templating-compile-and-create-content-selectors │ │ └── index.js │ ├── di-instance │ │ └── index.js │ ├── templating-compile-surrogate-behaviors │ │ └── index.js │ ├── templating-create-surrogate-behaviors │ │ └── index.js │ ├── di-auto-registration-with-metadata │ │ └── index.js │ ├── templating-compile-with-bindings-and-behaviors │ │ └── index.js │ ├── templating-create-with-bindings-and-behaviors │ │ └── index.js │ ├── templating-compile-and-create-with-bindings-and-behaviors │ │ └── index.js │ ├── di-instance-parent │ │ └── index.js │ ├── di-instance-parent4 │ │ └── index.js │ ├── di-create-child-container │ │ └── index.js │ ├── binding-parse-simple │ │ └── index.js │ ├── binding-parse-cached │ │ └── index.js │ ├── binding-parse-complex │ │ └── index.js │ ├── binding-interpolation-short │ │ └── index.js │ ├── container.js │ ├── binding-bind │ │ └── index.js │ ├── binding-bind-interpolation │ │ └── index.js │ ├── binding-observer-locator │ │ └── index.js │ ├── binding-interpolation-long │ │ └── index.js │ └── templating.js └── macro │ ├── simple-form │ ├── app.js │ ├── index.html │ ├── main.js │ └── app.html │ └── simple-table │ ├── index.html │ ├── main.js │ ├── app.html │ └── app.js ├── server ├── controllers │ ├── static.js │ ├── tests.js │ └── tags.js ├── main.js └── fsutil │ └── directory.js ├── .editorconfig ├── CONTRIBUTING.md ├── LICENSE ├── benchmark-plan.md ├── ISSUE_TEMPLATE.md ├── package.json ├── optimization-plan.md ├── README.md └── config.js /dist/tags/tags.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true 3 | } 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | jspm_packages 2 | bower_components 3 | .idea -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | require('require-dir')('build/tasks'); 2 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6" 4 | } 5 | } -------------------------------------------------------------------------------- /app/benchmark-resources/content-selectors.js: -------------------------------------------------------------------------------- 1 | export class ContentSelectors { 2 | } 3 | -------------------------------------------------------------------------------- /app/benchmarking/type.js: -------------------------------------------------------------------------------- 1 | export var type = { 2 | micro: 'micro', 3 | macro: 'macro' 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | jspm_packages 3 | bower_components 4 | /dist 5 | .idea 6 | .DS_STORE 7 | -------------------------------------------------------------------------------- /app/benchmark-resources/point.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/resources/skip-value-converter.js: -------------------------------------------------------------------------------- 1 | export class SkipValueConverter { 2 | toView(array, count) { 3 | return array.slice(count); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /app/benchmarking/definition.js: -------------------------------------------------------------------------------- 1 | export class Definition { 2 | constructor(name, type) { 3 | this.name = name; 4 | this.type = type; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /app/resources/take-value-converter.js: -------------------------------------------------------------------------------- 1 | export class TakeValueConverter { 2 | toView(array, count) { 3 | return array.slice(0, count); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /app/benchmark-resources/surrogate-behaviors.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /app/resources/index.js: -------------------------------------------------------------------------------- 1 | export function configure(framework) { 2 | framework.globalResources( 3 | './skip-value-converter', 4 | './take-value-converter' 5 | ); 6 | } 7 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-vanilla/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewCompiler', template.vanilla); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-create-vanilla/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewFactory', template.vanilla); 4 | -------------------------------------------------------------------------------- /app/benchmark-resources/point.js: -------------------------------------------------------------------------------- 1 | import {customElement, bindable} from 'aurelia-framework'; 2 | 3 | @customElement('point') 4 | export class Point { 5 | @bindable x; 6 | @bindable y; 7 | } -------------------------------------------------------------------------------- /app/benchmark-resources/template-parts.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /benchmarks/micro/di-singleton/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerSingleton(ctor)); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/di-transient/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerTransient(ctor)); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-and-create-vanilla/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('Both', template.vanilla); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-create-with-bindings/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewFactory', template.bindingsOnly); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-and-create-with-bindings/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('Both', template.bindingsOnly); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-template-parts/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewCompiler', template.templateParts); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-with-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewCompiler', template.behaviorsOnly); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-with-bindings/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewCompiler', template.bindingsOnly); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-create-template-parts/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewFactory', template.templateParts); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-create-with-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewFactory', template.behaviorsOnly); 4 | -------------------------------------------------------------------------------- /app/benchmark-resources/template-parts.js: -------------------------------------------------------------------------------- 1 | import {customElement, bindable} from 'aurelia-framework'; 2 | 3 | @customElement('template-parts') 4 | export class TemplateParts { 5 | @bindable items; 6 | } 7 | -------------------------------------------------------------------------------- /benchmarks/micro/di-singleton-parent/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerSingleton(ctor), 0, 1); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/di-singleton-parent4/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerSingleton(ctor), 2, 6); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/di-transient-parent/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerTransient(ctor), 2, 6); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/di-transient-parent4/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerTransient(ctor), 2, 6); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-and-create-template-parts/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('Both', template.templateParts); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-and-create-with-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('Both', template.behaviorsOnly); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-content-selectors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewCompiler', template.contentSelectors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-create-content-selectors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewFactory', template.contentSelectors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/di-auto-registration-sans-metadata/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.autoRegister(ctor)); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-and-create-content-selectors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('Both', template.contentSelectors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/di-instance/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerInstance(ctor, 'How much do you bench?')); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-surrogate-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewCompiler', template.compileSurrogateBehaviors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-create-surrogate-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewFactory', template.createSurrogateBehaviors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/di-auto-registration-with-metadata/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.autoRegister(ctor), 0, 0, true); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-with-bindings-and-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewCompiler', template.bindingsAndBehaviors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-create-with-bindings-and-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('ViewFactory', template.bindingsAndBehaviors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/templating-compile-and-create-with-bindings-and-behaviors/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark, template} from '../templating'; 2 | 3 | export default createBenchmark('Both', template.bindingsAndBehaviors); 4 | -------------------------------------------------------------------------------- /benchmarks/micro/di-instance-parent/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerInstance(ctor, 'How much do you bench?'), 0, 1); 5 | -------------------------------------------------------------------------------- /benchmarks/micro/di-instance-parent4/index.js: -------------------------------------------------------------------------------- 1 | import {createBenchmark} from '../container'; 2 | 3 | export default createBenchmark( 4 | (container, ctor) => container.registerInstance(ctor, 'How much do you bench?'), 0, 1); 5 | -------------------------------------------------------------------------------- /app/benchmark-resources/content-selectors.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /app/benchmark-resources/index.js: -------------------------------------------------------------------------------- 1 | export function configure(config) { 2 | config.globalResources( 3 | './attributes', 4 | './point', 5 | './content-selectors', 6 | './template-parts', 7 | './surrogate-behaviors'); 8 | } 9 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-form/app.js: -------------------------------------------------------------------------------- 1 | export class App { 2 | fromAirport = 'JFK'; 3 | toAirport = 'LHR'; 4 | departureDate = '7/29/2015'; 5 | returnDate = '8/13/2015'; 6 | passengers = 2; 7 | includeNearby = false; 8 | flexibleDates = true; 9 | } 10 | -------------------------------------------------------------------------------- /app/benchmark-resources/surrogate-behaviors.js: -------------------------------------------------------------------------------- 1 | import {customElement} from 'aurelia-framework'; 2 | 3 | @customElement('surrogate-behaviors') 4 | export class SurrogateBehaviors { 5 | foo = 'foo'; 6 | bar = 'bar'; 7 | baz = 'baz'; 8 | world = 'world'; 9 | } 10 | -------------------------------------------------------------------------------- /app/util/user-agent.js: -------------------------------------------------------------------------------- 1 | import UAParser from 'faisalman/ua-parser-js/ua-parser.min.js'; 2 | 3 | let parser = new UAParser(), 4 | browser = parser.getBrowser(), // {name, version} 5 | os = parser.getOS(); // {name, version} 6 | 7 | export var userAgent = `${browser.name} on ${os.name} ${os.version}`; 8 | -------------------------------------------------------------------------------- /server/controllers/static.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | 4 | router.get("/", function(request, response) { 5 | response.redirect("/dist/app/index.html"); 6 | }); 7 | 8 | router.use(express.static(__dirname + "/../../")); 9 | 10 | module.exports = router; 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | [**.*] 13 | indent_style = space 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-form/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Simple Form 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-table/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Simple Form 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/micro/di-create-child-container/index.js: -------------------------------------------------------------------------------- 1 | import {Container} from 'aurelia-framework'; 2 | 3 | export default deferred => { 4 | var container = new Container(), current, i = 100, j; 5 | while(i--) { 6 | current = container.createChild(); 7 | j = 50; 8 | while(j--) { 9 | current = current.createChild(); 10 | } 11 | } 12 | deferred.resolve(); 13 | }; 14 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-form/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener( 2 | "aurelia-composed", 3 | () => parent.postMessage("test-end", "*"), false); 4 | 5 | export function configure(aurelia) { 6 | console.log('start'); 7 | parent.postMessage("test-start", "*"); 8 | aurelia.use 9 | .standardConfiguration() 10 | .developmentLogging(); 11 | 12 | aurelia.start().then(a => a.setRoot()); 13 | } 14 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-table/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener( 2 | "aurelia-composed", 3 | () => parent.postMessage("test-end", "*"), false); 4 | 5 | export function configure(aurelia) { 6 | console.log('start'); 7 | parent.postMessage("test-start", "*"); 8 | aurelia.use 9 | .standardConfiguration() 10 | .developmentLogging(); 11 | 12 | aurelia.start().then(a => a.setRoot()); 13 | } 14 | -------------------------------------------------------------------------------- /app/util/parse-json.js: -------------------------------------------------------------------------------- 1 | function dateReviver(name, value) { 2 | if (typeof value === 'string') { 3 | var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); 4 | if (a) { 5 | return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])); 6 | } 7 | } 8 | return value; 9 | } 10 | 11 | export function parseJson(json) { 12 | return JSON.parse(json, dateReviver); 13 | } 14 | -------------------------------------------------------------------------------- /server/main.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var bodyParser = require('body-parser'); 3 | var app = express(); 4 | 5 | app.use(bodyParser.json()) 6 | app.use(require('./controllers/static.js')); 7 | app.use('/api/tests', require('./controllers/tests.js')); 8 | app.use('/api/tags', require('./controllers/tags.js')); 9 | 10 | var port = 8080; 11 | app.listen(port, function(){ 12 | console.log('Server listening on', port); 13 | }); 14 | -------------------------------------------------------------------------------- /app/ui/harness/result-set.html: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /benchmarks/micro/binding-parse-simple/index.js: -------------------------------------------------------------------------------- 1 | import {Parser} from 'aurelia-framework'; 2 | 3 | var expressions = [], i; 4 | for(i = 0; i < 100; i++) { 5 | expressions.push('memberAccessExpression' + i); 6 | } 7 | 8 | export default deferred => { 9 | var parser = new Parser(), expression; 10 | i = expressions.length; 11 | while(i--) { 12 | expression = expressions[i]; 13 | parser.parse(expression); 14 | } 15 | deferred.resolve(); 16 | }; 17 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-table/app.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /server/controllers/tests.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var directory = require('../fsutil/directory'); 3 | var router = express.Router(); 4 | 5 | router.get('/', function(request, response) { 6 | var microTests = directory.getChildren('/benchmarks/micro'); 7 | var macroTests = directory.getChildren('/benchmarks/macro'); 8 | 9 | response.json({ 10 | micro : microTests, 11 | macro: macroTests 12 | }); 13 | }); 14 | 15 | module.exports = router; 16 | -------------------------------------------------------------------------------- /app/styles.css: -------------------------------------------------------------------------------- 1 | .host { 2 | margin-top: 4em; 3 | } 4 | 5 | .running-indicator { 6 | margin-top: 0.5em; 7 | } 8 | 9 | /** 10 | * harness view 11 | */ 12 | .harness .tagged-result { 13 | font-weight: bold; 14 | } 15 | 16 | .harness .user-agent { 17 | display: inline-block; 18 | width: 15em; 19 | text-align: right; 20 | } 21 | 22 | .harness th > form { 23 | font-weight: normal; 24 | } 25 | 26 | .harness .tagged { 27 | font-weight: bold; 28 | } 29 | 30 | /** 31 | * results view 32 | */ 33 | -------------------------------------------------------------------------------- /app/benchmark-resources/attributes.js: -------------------------------------------------------------------------------- 1 | import {customAttribute, inject} from 'aurelia-framework'; 2 | 3 | @inject(Element) 4 | class Attr { 5 | constructor(element) { 6 | this.element = element; 7 | } 8 | 9 | attached() { 10 | console.log(`attached to ${this.element.outerHTML}`); 11 | } 12 | } 13 | 14 | @customAttribute('foo') 15 | export class Foo extends Attr {} 16 | 17 | @customAttribute('bar') 18 | export class Bar extends Attr {} 19 | 20 | @customAttribute('baz') 21 | export class Baz extends Attr {} -------------------------------------------------------------------------------- /benchmarks/micro/binding-parse-cached/index.js: -------------------------------------------------------------------------------- 1 | import {Parser} from 'aurelia-framework'; 2 | 3 | var parser = new Parser(), 4 | simple = 'memberAccessExpresion', 5 | complex = 'some.complex.expression[that](is, really, complex).and.expensive[3].to.parse ? "and" : "long" | withAConverter:and:parameters'; 6 | parser.parse(simple); 7 | parser.parse(complex); 8 | 9 | export default deferred => { 10 | var i = 100; 11 | while(i--) { 12 | parser.parse(simple); 13 | parser.parse(complex); 14 | } 15 | deferred.resolve(); 16 | }; 17 | -------------------------------------------------------------------------------- /app/benchmarking/result-factory.js: -------------------------------------------------------------------------------- 1 | import {userAgent} from '../util/user-agent'; 2 | 3 | export class ResultFactory { 4 | fromMeasures(name, measures) { 5 | let deltas = measures.heapDeltas.filter(x => x >= 0); // filter out drops due to GC 6 | let averageHeapDelta = deltas.length ? Math.floor(deltas.reduce((a, b) => a + b) / deltas.length) : 0; 7 | return { 8 | name: name, 9 | timestamp: new Date(), 10 | userAgent: userAgent, 11 | period: measures.period, 12 | heapDelta: averageHeapDelta, 13 | tag: '' 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-table/app.js: -------------------------------------------------------------------------------- 1 | export class App { 2 | planets = [ 3 | { name: 'Mercury', diameter: 3032, distance: 35983610 }, 4 | { name: 'Venus', diameter: 7521, distance: 67232360 }, 5 | { name: 'Earth', diameter: 7926, distance: 92957100 }, 6 | { name: 'Mars', diameter: 4222, distance: 141635300 }, 7 | { name: 'Jupiter', diameter: 88846, distance: 483632000 }, 8 | { name: 'Saturn', diameter: 74898, distance: 888188000 }, 9 | { name: 'Uranus', diameter: 31763, distance: 1783950000 }, 10 | { name: 'Neptune', diameter: 30778, distance: 2798842000 }, 11 | ]; 12 | } 13 | -------------------------------------------------------------------------------- /benchmarks/macro/simple-form/app.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We'd love for you to contribute and to make this project even better than it is today! If this interests you, please begin by reading [our contributing guidelines](https://github.com/DurandalProject/about/blob/master/CONTRIBUTING.md). The contributing document will provide you with all the information you need to get started. Once you have read that, you will need to also [sign our CLA](http://goo.gl/forms/dI8QDDSyKR) before we can accept a Pull Request from you. More information on the process is included in the [contributor's guide](https://github.com/DurandalProject/about/blob/master/CONTRIBUTING.md). 4 | -------------------------------------------------------------------------------- /app/ui/app.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /app/ui/app.js: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Coordinator} from '../benchmarking/coordinator'; 3 | 4 | @inject(Coordinator) 5 | export class App { 6 | constructor(coordinator) { 7 | this.coordinator = coordinator; 8 | } 9 | 10 | configureRouter(config, router){ 11 | config.title = 'Benchmarks'; 12 | config.map([ 13 | { route: '', redirect: 'harness' }, 14 | { route: 'harness', name: 'harness', moduleId: 'ui/harness/harness', nav: true, title: 'Harness' }, 15 | { route: 'tags', name: 'tags', moduleId: 'ui/tags/tags', nav: true, title: 'Tags' }, 16 | ]); 17 | 18 | this.router = router; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/controllers/tags.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var directory = require('../fsutil/directory'); 4 | var basePath = 'dist/tags/'; 5 | 6 | router.get('/', function(request, response) { 7 | var name = 'tags.json'; 8 | var options = { 9 | headers: { "Content-Type": "json" }, 10 | root: __dirname + "/../../" + basePath 11 | }; 12 | response.sendFile(name, options); 13 | }); 14 | 15 | router.post('/', function(request, response) { 16 | var name = 'tags.json'; 17 | var results = request.body; 18 | directory.make(basePath); 19 | directory.writeFile(basePath + name, JSON.stringify(results, null, 2)); 20 | response.end(); 21 | }); 22 | 23 | module.exports = router; 24 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Benchmarks 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/ui/tags/chart.js: -------------------------------------------------------------------------------- 1 | import {inject, customElement, bindable, noView, processContent} from 'aurelia-framework'; 2 | import Chartist from 'chartist'; 3 | 4 | @customElement('chart') 5 | @inject(Element) 6 | @noView() 7 | @processContent(false) 8 | export class Chart { 9 | @bindable data; 10 | @bindable options; 11 | @bindable type; 12 | chart = null; 13 | 14 | constructor(element) { 15 | this.element = element; 16 | } 17 | 18 | propertyChanged(name, newValue, oldValue) { 19 | if (this.chart) { 20 | this.chart.detach(); 21 | this.chart = null; 22 | } 23 | if (this.data && this.options && this.type) { 24 | this.chart = Chartist[this.type](this.element, this.data, this.options); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/benchmarking/definition-repository.js: -------------------------------------------------------------------------------- 1 | import {Definition} from './definition'; 2 | import {type} from './type'; 3 | import {HttpClient} from 'aurelia-http-client'; 4 | import {inject} from 'aurelia-dependency-injection'; 5 | import {parseJson} from '../util/parse-json'; 6 | 7 | @inject(HttpClient) 8 | export class DefinitionRepository { 9 | definitions = null; 10 | 11 | constructor(http) { 12 | this.http = http; 13 | } 14 | 15 | load() { 16 | return this.http.get('/api/tests') 17 | .then(message => { 18 | let result = parseJson(message.response); 19 | 20 | this.definitions = result.micro.map(name => new Definition(name, type.micro)) 21 | .concat(result.macro.map(name => new Definition(name, type.macro))); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /server/fsutil/directory.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var mkdirp = require('mkdirp'); 3 | 4 | var getChildren = function(directory) { 5 | var base = __dirname + "/../.." + directory; 6 | return fs.readdirSync(base).filter(function(file) { 7 | return fs.statSync(base + '/' + file).isDirectory(); 8 | }); 9 | }; 10 | 11 | var getFileNames = function(directory) { 12 | return fs.readdirSync(directory); 13 | }; 14 | 15 | var make = function(path) { 16 | mkdirp.sync(path); 17 | }; 18 | 19 | var writeFile = function(path, contents) { 20 | fs.writeFileSync(path, contents); 21 | }; 22 | 23 | module.exports = { 24 | getChildren: getChildren, 25 | make: make, 26 | writeFile: writeFile, 27 | getFileNames: getFileNames, 28 | exists: function(path) { return fs.existsSync(path); } 29 | }; 30 | -------------------------------------------------------------------------------- /app/ui/harness/result-set.js: -------------------------------------------------------------------------------- 1 | import {bindable, customElement} from 'aurelia-framework'; 2 | 3 | @customElement('result-set') 4 | export class ResultSet { 5 | @bindable results; 6 | 7 | getTextClass(result, field) { 8 | let change = this.compare(result, field); 9 | return !change || change.same ? 'text-muted' : (change.improved ? 'text-success' : 'text-danger'); 10 | } 11 | 12 | compare(result, field) { 13 | var previous = this.getPrevious(result); 14 | if (previous) { 15 | let p = (result[field] - previous[field]) / previous[field] * 100; 16 | return { 17 | same: Math.abs(p) <= 15, 18 | improved: p < -15, 19 | percentImprovement: p 20 | } 21 | } 22 | return null; 23 | } 24 | 25 | getPrevious(result) { 26 | let i = this.results.indexOf(result); 27 | return this.results[i + 1]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/main.js: -------------------------------------------------------------------------------- 1 | import {HttpClient} from 'aurelia-http-client'; 2 | 3 | export function configure(aurelia) { 4 | aurelia.use 5 | .standardConfiguration() 6 | .developmentLogging() 7 | .feature('./resources') 8 | .feature('./benchmark-resources'); 9 | 10 | // configure the http client. 11 | let http = aurelia.container.get(HttpClient); 12 | http.configure(x => x.withHeader('Content-Type', 'application/json')); 13 | aurelia.container.registerInstance(HttpClient, http); 14 | 15 | // register the iframe element used by the macro benchmark runner. 16 | let iframe = document.createElement('iframe'); 17 | iframe.style.display = 'none'; 18 | aurelia.container.registerInstance(HTMLIFrameElement, iframe); 19 | 20 | aurelia.start().then(a => a.setRoot('ui/app')) 21 | .then(() => document.body.appendChild(iframe)); // add the iframe to the body after the app is composed. 22 | } 23 | -------------------------------------------------------------------------------- /app/benchmarking/macro-runner.js: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | 3 | @inject(HTMLIFrameElement) 4 | export class MacroRunner { 5 | constructor(iframe) { 6 | this.iframe = iframe; 7 | } 8 | 9 | run(name) { 10 | return new Promise((resolve, reject) => { 11 | let start, finish; 12 | 13 | let handleMessage = event => { 14 | if (event.data === 'test-start') { 15 | start = new Date(); 16 | return; 17 | } 18 | if (event.data !== 'test-end') { 19 | return; 20 | } 21 | finish = new Date(); 22 | 23 | window.removeEventListener('message', handleMessage) 24 | this.iframe.src = 'about:blank'; 25 | 26 | resolve({ period: (finish - start) / 1000.0, heapDeltas: [] }); 27 | }; 28 | 29 | window.addEventListener('message', handleMessage); 30 | this.iframe.src = `/benchmarks/macro/${name}/index.html`; 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2010 - 2016 Blue Spire Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /benchmarks/micro/binding-parse-complex/index.js: -------------------------------------------------------------------------------- 1 | import {Parser} from 'aurelia-framework'; 2 | 3 | var expressions = [], i; 4 | 5 | for(i = 0; i < 100; i++) { 6 | expressions.push('a.path.expression' + i); 7 | expressions.push('accessKeyedExpression[' + i + ']'); 8 | expressions.push('accessKeyedExpression[' + i + '].and.a.path.expression'); 9 | expressions.push('callScopeExpression' + i + '()'); 10 | expressions.push('callScopeExpression(' + i + ')'); 11 | expressions.push('callMember.expression(' + i + ')'); 12 | expressions.push('callMember.expression(' + i + ', true, false, 1, \'hello world\')'); 13 | expressions.push('a' + i + ' ? conditional : expression'); 14 | expressions.push('another ? more.complex : conditional[' + i + '].expression'); 15 | expressions.push('a' + i + ' | converter:expression'); 16 | expressions.push('another.more[' + i + '].complex | converter:expression:' + i); 17 | } 18 | 19 | export default deferred => { 20 | var parser = new Parser(), expression; 21 | i = expressions.length; 22 | while(i--) { 23 | expression = expressions[i]; 24 | parser.parse(expression); 25 | } 26 | deferred.resolve(); 27 | }; 28 | -------------------------------------------------------------------------------- /app/benchmarking/coordinator.js: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {type} from './type'; 3 | import {MicroRunner} from './micro-runner'; 4 | import {MacroRunner} from './macro-runner'; 5 | import {ResultFactory} from './result-factory'; 6 | import {ResultRepository} from './result-repository'; 7 | 8 | @inject(MicroRunner, MacroRunner, ResultFactory, ResultRepository) 9 | export class Coordinator { 10 | promise = Promise.resolve(null); 11 | active = null; 12 | 13 | constructor(micro, macro, resultFactory, results) { 14 | this.micro = micro; 15 | this.macro = macro; 16 | this.resultFactory = resultFactory; 17 | this.results = results; 18 | } 19 | 20 | enqueue(definition) { 21 | this.promise = this.promise.then(() => { 22 | this.active = definition; 23 | let runner = definition.type === type.micro ? this.micro : this.macro; 24 | return runner.run(definition.name) 25 | .then(measures => { 26 | let result = this.resultFactory.fromMeasures(definition.name, measures); 27 | this.results.add(result); 28 | this.active = null; 29 | }); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/ui/harness/harness.js: -------------------------------------------------------------------------------- 1 | import {inject} from 'aurelia-dependency-injection'; 2 | import {Coordinator} from '../../benchmarking/coordinator'; 3 | import {DefinitionRepository} from '../../benchmarking/definition-repository'; 4 | import {ResultRepository} from '../../benchmarking/result-repository'; 5 | import {BenchmarkViewModel} from '../benchmark-view-model'; 6 | 7 | @inject(DefinitionRepository, ResultRepository, Coordinator) 8 | export class Harness extends BenchmarkViewModel { 9 | isTagging = false; 10 | 11 | constructor(definitionRepository, resultRepository, coordinator) { 12 | super(definitionRepository, resultRepository); 13 | this.coordinator = coordinator; 14 | } 15 | 16 | run() { 17 | this.selectedDefinitions.forEach(::this.coordinator.enqueue); 18 | } 19 | 20 | tag(tag) { 21 | let names = this.selectedDefinitions.map(d => d.name); 22 | this.isTagging = true; 23 | this.resultRepository.tag(names, tag) 24 | .then(() => this.isTagging = false); 25 | } 26 | 27 | definitionClicked(definition, event) { 28 | let index = this.selectedDefinitions.indexOf(definition); 29 | if (index === -1) { 30 | this.selectedDefinitions.push(definition); 31 | } else { 32 | this.selectedDefinitions.splice(index, 1); 33 | } 34 | } 35 | 36 | canDeactivate() { 37 | return this.coordinator.active === null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /benchmarks/micro/binding-interpolation-short/index.js: -------------------------------------------------------------------------------- 1 | import {TemplatingBindingLanguage} from 'aurelia-templating-binding'; 2 | 3 | var parser = { parse: expression => null }, 4 | observerLocator = { getObserver: () => null }, 5 | syntaxInterpreter = {}, 6 | language = new TemplatingBindingLanguage(parser, observerLocator, syntaxInterpreter), 7 | resources = { valueConverterLookupFunction: () => null }, 8 | expressions = [ 9 | '${name}', 10 | '${\'foo\\\'\'}', 11 | '${name}', 12 | '${\'name\'}', 13 | '${\'name\\\'\'}', 14 | '${"name"}', 15 | '${"name\\\""}', 16 | '\\${name}', 17 | '\\\\${"name"}', 18 | 'foo${name}baz', 19 | ' ${name} ', 20 | '\'${name}\'', 21 | '"${name}"', 22 | 'foo bar baz', 23 | '${foo.bar.baz}', 24 | '${ name }', 25 | '${name | foo}', 26 | '${name | foo:bar}', 27 | '${name|test:{}}', 28 | '${name|test:\'{}\'}', 29 | '${name | test: { foo: 4, bar, 9 } }', 30 | 'foo ${name | test: { foo: 4, bar, 9 } } bar', 31 | '${firstName}${lastName}', 32 | ' ${firstName} ${lastName} ', 33 | '\\ ${foo}\\', 34 | ]; 35 | 36 | export default deferred => { 37 | var i = expressions.length, j, expression; 38 | while(i--) { 39 | expression = expressions[i]; 40 | j = 100; 41 | while(j--) { 42 | language.parseContent(resources, 'textContent', expression); 43 | } 44 | } 45 | deferred.resolve(); 46 | } 47 | -------------------------------------------------------------------------------- /app/benchmarking/micro-runner.js: -------------------------------------------------------------------------------- 1 | import {Benchmark} from 'benchmark'; 2 | 3 | // benchmark.js expects a global Benchmark object and at least one