1 | import 'aurelia-polyfills';
|
2 | import {PLATFORM, isInitialized} from 'aurelia-pal';
|
3 |
|
4 | let bootstrapPromises = [];
|
5 | let startResolve;
|
6 |
|
7 | const startPromise = new Promise(resolve => startResolve = resolve);
|
8 | const host = PLATFORM.global;
|
9 | const isNodeLike = typeof process !== 'undefined' && !process.browser;
|
10 |
|
11 | function ready() {
|
12 | if (!host.document || host.document.readyState === 'complete') {
|
13 | return Promise.resolve();
|
14 | }
|
15 |
|
16 | return new Promise(resolve => {
|
17 | host.document.addEventListener('DOMContentLoaded', completed);
|
18 | host.addEventListener('load', completed);
|
19 |
|
20 | function completed() {
|
21 | host.document.removeEventListener('DOMContentLoaded', completed);
|
22 | host.removeEventListener('load', completed);
|
23 | resolve();
|
24 | }
|
25 | });
|
26 | }
|
27 |
|
28 | function createLoader() {
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | if (PLATFORM.Loader) {
|
38 | return Promise.resolve(new PLATFORM.Loader());
|
39 | }
|
40 |
|
41 | if (typeof AURELIA_WEBPACK_2_0 === 'undefined') {
|
42 |
|
43 | if (typeof __webpack_require__ !== 'undefined') {
|
44 |
|
45 |
|
46 |
|
47 | const m = __webpack_require__(require.resolve('aurelia-loader-webpack'));
|
48 | return Promise.resolve(new m.WebpackLoader());
|
49 | }
|
50 |
|
51 |
|
52 | if (host.System && typeof host.System.config === 'function') {
|
53 | return host.System.normalize('aurelia-bootstrapper').then(bsn => {
|
54 | return host.System.normalize('aurelia-loader-default', bsn);
|
55 | }).then(loaderName => {
|
56 | return host.System.import(loaderName).then(m => new m.DefaultLoader());
|
57 | });
|
58 | }
|
59 |
|
60 |
|
61 | if (typeof host.require === 'function' && typeof host.require.version === 'string') {
|
62 | return new Promise((resolve, reject) => host.require(['aurelia-loader-default'], m => resolve(new m.DefaultLoader()), reject));
|
63 | }
|
64 |
|
65 |
|
66 | if (isNodeLike && typeof module !== 'undefined' && typeof module.require !== 'undefined') {
|
67 |
|
68 |
|
69 |
|
70 | const m = module.require('aurelia-loader-nodejs');
|
71 | return Promise.resolve(new m.NodeJsLoader());
|
72 | }
|
73 | }
|
74 |
|
75 | return Promise.reject('No PLATFORM.Loader is defined and there is neither a System API (ES6) or a Require API (AMD) globally available to load your app.');
|
76 | }
|
77 |
|
78 | function initializePal(loader) {
|
79 | let type;
|
80 |
|
81 | const isRenderer = isNodeLike && (process.type === 'renderer' || process.versions['node-webkit']);
|
82 |
|
83 | if (isNodeLike && !isRenderer) {
|
84 | type = 'nodejs';
|
85 | } else if (typeof window !== 'undefined') {
|
86 | type = 'browser';
|
87 | } else if (typeof self !== 'undefined') {
|
88 | type = 'worker';
|
89 | } else {
|
90 | throw new Error('Could not determine platform implementation to load.');
|
91 | }
|
92 |
|
93 |
|
94 |
|
95 |
|
96 | return loader.loadModule('aurelia-pal-' + type)
|
97 | .then(palModule => type === 'nodejs' && !isInitialized && palModule.globalize() || palModule.initialize());
|
98 | }
|
99 |
|
100 | function preparePlatform(loader) {
|
101 | const map = (moduleId, relativeTo) =>
|
102 | loader.normalize(moduleId, relativeTo)
|
103 | .then(normalized => {
|
104 | loader.map(moduleId, normalized);
|
105 | return normalized;
|
106 | });
|
107 |
|
108 | return initializePal(loader)
|
109 | .then(() => loader.normalize('aurelia-bootstrapper'))
|
110 | .then(bootstrapperName => {
|
111 |
|
112 |
|
113 |
|
114 | const frameworkPromise = map(PLATFORM.moduleName('aurelia-framework', { exports: ['Aurelia'] }),
|
115 | bootstrapperName);
|
116 |
|
117 |
|
118 | return Promise.all([
|
119 | frameworkPromise,
|
120 | frameworkPromise.then(frameworkName => map('aurelia-dependency-injection', frameworkName)),
|
121 | map('aurelia-router', bootstrapperName),
|
122 | map('aurelia-logging-console', bootstrapperName)
|
123 | ]);
|
124 | })
|
125 | .then(([frameworkName]) => loader.loadModule(frameworkName))
|
126 | .then(fx => startResolve(() => new fx.Aurelia(loader)));
|
127 | }
|
128 |
|
129 | function config(appHost, configModuleId, aurelia) {
|
130 | aurelia.host = appHost;
|
131 | aurelia.configModuleId = configModuleId || null;
|
132 |
|
133 | if (configModuleId) {
|
134 | return aurelia.loader
|
135 | .loadModule(configModuleId)
|
136 | .then(customConfig => {
|
137 | if (!customConfig.configure) {
|
138 | throw new Error(`Cannot initialize module '${configModuleId}' without a configure function.`);
|
139 | }
|
140 |
|
141 | return customConfig.configure(aurelia);
|
142 | });
|
143 | }
|
144 |
|
145 | aurelia.use
|
146 | .standardConfiguration()
|
147 | .developmentLogging();
|
148 |
|
149 | return aurelia.start().then(() => aurelia.setRoot());
|
150 | }
|
151 |
|
152 | function run() {
|
153 | return ready()
|
154 | .then(createLoader)
|
155 | .then(preparePlatform)
|
156 | .then(() => {
|
157 | const appHosts = host.document.querySelectorAll('[aurelia-app],[data-aurelia-app]');
|
158 | for (let i = 0, ii = appHosts.length; i < ii; ++i) {
|
159 | const appHost = appHosts[i];
|
160 | const moduleId = appHost.getAttribute('aurelia-app') || appHost.getAttribute('data-aurelia-app');
|
161 | bootstrap(config.bind(null, appHost, moduleId));
|
162 | }
|
163 |
|
164 |
|
165 |
|
166 | const toConsole = console.error.bind(console);
|
167 | const bootstraps = bootstrapPromises.map(p => p.catch(toConsole));
|
168 | bootstrapPromises = null;
|
169 | return Promise.all(bootstraps);
|
170 | });
|
171 | }
|
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
|
178 | export function bootstrap(configure: Function): Promise<void> {
|
179 | const p = startPromise.then(factory => configure(factory()));
|
180 | if (bootstrapPromises) bootstrapPromises.push(p);
|
181 | return p;
|
182 | }
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 | export const starting = run();
|