UNPKG

systemjs

Version:

System loader extension for flexible AMD & CommonJS support

1,674 lines (1,406 loc) 52.1 kB
/* * SystemJS v0.18.0 */ (function(__global) { var isWorker = typeof window == 'undefined' && typeof self != 'undefined' && typeof importScripts != 'undefined'; var isBrowser = typeof window != 'undefined' && typeof document != 'undefined'; var isWindows = typeof process != 'undefined' && !!process.platform.match(/^win/); if (!__global.console) __global.console = { assert: function() {} }; // IE8 support var indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, thisLen = this.length; i < thisLen; i++) { if (this[i] === item) { return i; } } return -1; }; var defineProperty; (function () { try { if (!!Object.defineProperty({}, 'a', {})) defineProperty = Object.defineProperty; } catch (e) { defineProperty = function(obj, prop, opt) { try { obj[prop] = opt.value || opt.get.call(obj); } catch(e) {} } } })(); function addToError(err, msg) { var newErr; if (err instanceof Error) { var newErr = new Error(err.message, err.fileName, err.lineNumber); newErr.message = err.message + '\n\t' + msg; newErr.stack = err.stack; } else { newErr = err + '\n\t' + msg; } return newErr; } function __eval(source, debugName, context) { try { new Function(source).call(context); } catch(e) { throw addToError(e, 'Evaluating ' + debugName); } } var baseURI; // environent baseURI detection if (typeof document != 'undefined' && document.getElementsByTagName) { baseURI = document.baseURI; if (!baseURI) { var bases = document.getElementsByTagName('base'); baseURI = bases[0] && bases[0].href || window.location.href; } // sanitize out the hash and querystring baseURI = baseURI.split('#')[0].split('?')[0]; baseURI = baseURI.substr(0, baseURI.lastIndexOf('/') + 1); } else if (typeof process != 'undefined' && process.cwd) { baseURI = 'file://' + (isWindows ? '/' : '') + process.cwd() + '/'; if (isWindows) baseURI = baseURI.replace(/\\/g, '/'); } else if (typeof location != 'undefined') { baseURI = __global.location.href; } else { throw new TypeError('No environment baseURI'); } var URL = typeof __global.URL == 'function' && __global.URL || URLPolyfill; /* ********************************************************************************************* Dynamic Module Loader Polyfill - Implemented exactly to the former 2014-08-24 ES6 Specification Draft Rev 27, Section 15 http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#august_24_2014_draft_rev_27 - Functions are commented with their spec numbers, with spec differences commented. - Spec bugs are commented in this code with links. - Abstract functions have been combined where possible, and their associated functions commented. - Realm implementation is entirely omitted. ********************************************************************************************* */ function Module() {} function Loader(options) { this._loader = { loaderObj: this, loads: [], modules: {}, importPromises: {}, moduleRecords: {} }; // 26.3.3.6 defineProperty(this, 'global', { get: function() { return __global; } }); // 26.3.3.13 realm not implemented } (function() { // Some Helpers // logs a linkset snapshot for debugging /* function snapshot(loader) { console.log('---Snapshot---'); for (var i = 0; i < loader.loads.length; i++) { var load = loader.loads[i]; var linkSetLog = ' ' + load.name + ' (' + load.status + '): '; for (var j = 0; j < load.linkSets.length; j++) { linkSetLog += '{' + logloads(load.linkSets[j].loads) + '} '; } console.log(linkSetLog); } console.log(''); } function logloads(loads) { var log = ''; for (var k = 0; k < loads.length; k++) log += loads[k].name + (k != loads.length - 1 ? ' ' : ''); return log; } */ /* function checkInvariants() { // see https://bugs.ecmascript.org/show_bug.cgi?id=2603#c1 var loads = System._loader.loads; var linkSets = []; for (var i = 0; i < loads.length; i++) { var load = loads[i]; console.assert(load.status == 'loading' || load.status == 'loaded', 'Each load is loading or loaded'); for (var j = 0; j < load.linkSets.length; j++) { var linkSet = load.linkSets[j]; for (var k = 0; k < linkSet.loads.length; k++) console.assert(loads.indexOf(linkSet.loads[k]) != -1, 'linkSet loads are a subset of loader loads'); if (linkSets.indexOf(linkSet) == -1) linkSets.push(linkSet); } } for (var i = 0; i < loads.length; i++) { var load = loads[i]; for (var j = 0; j < linkSets.length; j++) { var linkSet = linkSets[j]; if (linkSet.loads.indexOf(load) != -1) console.assert(load.linkSets.indexOf(linkSet) != -1, 'linkSet contains load -> load contains linkSet'); if (load.linkSets.indexOf(linkSet) != -1) console.assert(linkSet.loads.indexOf(load) != -1, 'load contains linkSet -> linkSet contains load'); } } for (var i = 0; i < linkSets.length; i++) { var linkSet = linkSets[i]; for (var j = 0; j < linkSet.loads.length; j++) { var load = linkSet.loads[j]; for (var k = 0; k < load.dependencies.length; k++) { var depName = load.dependencies[k].value; var depLoad; for (var l = 0; l < loads.length; l++) { if (loads[l].name != depName) continue; depLoad = loads[l]; break; } // loading records are allowed not to have their dependencies yet // if (load.status != 'loading') // console.assert(depLoad, 'depLoad found'); // console.assert(linkSet.loads.indexOf(depLoad) != -1, 'linkset contains all dependencies'); } } } } */ // 15.2.3 - Runtime Semantics: Loader State // 15.2.3.11 function createLoaderLoad(object) { return { // modules is an object for ES5 implementation modules: {}, loads: [], loaderObj: object }; } // 15.2.3.2 Load Records and LoadRequest Objects // 15.2.3.2.1 function createLoad(name) { return { status: 'loading', name: name, linkSets: [], dependencies: [], metadata: {} }; } // 15.2.3.2.2 createLoadRequestObject, absorbed into calling functions // 15.2.4 // 15.2.4.1 function loadModule(loader, name, options) { return new Promise(asyncStartLoadPartwayThrough({ step: options.address ? 'fetch' : 'locate', loader: loader, moduleName: name, // allow metadata for import https://bugs.ecmascript.org/show_bug.cgi?id=3091 moduleMetadata: options && options.metadata || {}, moduleSource: options.source, moduleAddress: options.address })); } // 15.2.4.2 function requestLoad(loader, request, refererName, refererAddress) { // 15.2.4.2.1 CallNormalize return new Promise(function(resolve, reject) { resolve(loader.loaderObj.normalize(request, refererName, refererAddress)); }) // 15.2.4.2.2 GetOrCreateLoad .then(function(name) { var load; if (loader.modules[name]) { load = createLoad(name); load.status = 'linked'; // https://bugs.ecmascript.org/show_bug.cgi?id=2795 load.module = loader.modules[name]; return load; } for (var i = 0, l = loader.loads.length; i < l; i++) { load = loader.loads[i]; if (load.name != name) continue; console.assert(load.status == 'loading' || load.status == 'loaded', 'loading or loaded'); return load; } load = createLoad(name); loader.loads.push(load); proceedToLocate(loader, load); return load; }); } // 15.2.4.3 function proceedToLocate(loader, load) { proceedToFetch(loader, load, Promise.resolve() // 15.2.4.3.1 CallLocate .then(function() { return loader.loaderObj.locate({ name: load.name, metadata: load.metadata }); }) ); } // 15.2.4.4 function proceedToFetch(loader, load, p) { proceedToTranslate(loader, load, p // 15.2.4.4.1 CallFetch .then(function(address) { // adjusted, see https://bugs.ecmascript.org/show_bug.cgi?id=2602 if (load.status != 'loading') return; load.address = address; return loader.loaderObj.fetch({ name: load.name, metadata: load.metadata, address: address }); }) ); } var anonCnt = 0; // 15.2.4.5 function proceedToTranslate(loader, load, p) { p // 15.2.4.5.1 CallTranslate .then(function(source) { if (load.status != 'loading') return; return Promise.resolve(loader.loaderObj.translate({ name: load.name, metadata: load.metadata, address: load.address, source: source })) // 15.2.4.5.2 CallInstantiate .then(function(source) { load.source = source; return loader.loaderObj.instantiate({ name: load.name, metadata: load.metadata, address: load.address, source: source }); }) // 15.2.4.5.3 InstantiateSucceeded .then(function(instantiateResult) { if (instantiateResult === undefined) { load.address = load.address || '<Anonymous Module ' + ++anonCnt + '>'; // instead of load.kind, use load.isDeclarative load.isDeclarative = true; return transpile.call(loader.loaderObj, load) .then(function(transpiled) { // Hijack System.register to set declare function var curSystem = __global.System; var curRegister = curSystem.register; curSystem.register = function(name, deps, declare) { if (typeof name != 'string') { declare = deps; deps = name; } // store the registered declaration as load.declare // store the deps as load.deps load.declare = declare; load.depsList = deps; } // empty {} context is closest to undefined 'this' we can get __eval(transpiled, load.address, {}); curSystem.register = curRegister; }); } else if (typeof instantiateResult == 'object') { load.depsList = instantiateResult.deps || []; load.execute = instantiateResult.execute; load.isDeclarative = false; } else throw TypeError('Invalid instantiate return value'); }) // 15.2.4.6 ProcessLoadDependencies .then(function() { load.dependencies = []; var depsList = load.depsList; var loadPromises = []; for (var i = 0, l = depsList.length; i < l; i++) (function(request, index) { loadPromises.push( requestLoad(loader, request, load.name, load.address) // 15.2.4.6.1 AddDependencyLoad (load is parentLoad) .then(function(depLoad) { // adjusted from spec to maintain dependency order // this is due to the System.register internal implementation needs load.dependencies[index] = { key: request, value: depLoad.name }; if (depLoad.status != 'linked') { var linkSets = load.linkSets.concat([]); for (var i = 0, l = linkSets.length; i < l; i++) addLoadToLinkSet(linkSets[i], depLoad); } // console.log('AddDependencyLoad ' + depLoad.name + ' for ' + load.name); // snapshot(loader); }) ); })(depsList[i], i); return Promise.all(loadPromises); }) // 15.2.4.6.2 LoadSucceeded .then(function() { // console.log('LoadSucceeded ' + load.name); // snapshot(loader); console.assert(load.status == 'loading', 'is loading'); load.status = 'loaded'; var linkSets = load.linkSets.concat([]); for (var i = 0, l = linkSets.length; i < l; i++) updateLinkSetOnLoad(linkSets[i], load); }); }) // 15.2.4.5.4 LoadFailed ['catch'](function(exc) { load.status = 'failed'; load.exception = exc; var linkSets = load.linkSets.concat([]); for (var i = 0, l = linkSets.length; i < l; i++) { linkSetFailed(linkSets[i], load, exc); } console.assert(load.linkSets.length == 0, 'linkSets not removed'); }); } // 15.2.4.7 PromiseOfStartLoadPartwayThrough absorbed into calling functions // 15.2.4.7.1 function asyncStartLoadPartwayThrough(stepState) { return function(resolve, reject) { var loader = stepState.loader; var name = stepState.moduleName; var step = stepState.step; if (loader.modules[name]) throw new TypeError('"' + name + '" already exists in the module table'); // adjusted to pick up existing loads var existingLoad; for (var i = 0, l = loader.loads.length; i < l; i++) { if (loader.loads[i].name == name) { existingLoad = loader.loads[i]; if(step == 'translate' && !existingLoad.source) { existingLoad.address = stepState.moduleAddress; proceedToTranslate(loader, existingLoad, Promise.resolve(stepState.moduleSource)); } return existingLoad.linkSets[0].done.then(function() { resolve(existingLoad); }); } } var load = createLoad(name); load.metadata = stepState.moduleMetadata; var linkSet = createLinkSet(loader, load); loader.loads.push(load); resolve(linkSet.done); if (step == 'locate') proceedToLocate(loader, load); else if (step == 'fetch') proceedToFetch(loader, load, Promise.resolve(stepState.moduleAddress)); else { console.assert(step == 'translate', 'translate step'); load.address = stepState.moduleAddress; proceedToTranslate(loader, load, Promise.resolve(stepState.moduleSource)); } } } // Declarative linking functions run through alternative implementation: // 15.2.5.1.1 CreateModuleLinkageRecord not implemented // 15.2.5.1.2 LookupExport not implemented // 15.2.5.1.3 LookupModuleDependency not implemented // 15.2.5.2.1 function createLinkSet(loader, startingLoad) { var linkSet = { loader: loader, loads: [], startingLoad: startingLoad, // added see spec bug https://bugs.ecmascript.org/show_bug.cgi?id=2995 loadingCount: 0 }; linkSet.done = new Promise(function(resolve, reject) { linkSet.resolve = resolve; linkSet.reject = reject; }); addLoadToLinkSet(linkSet, startingLoad); return linkSet; } // 15.2.5.2.2 function addLoadToLinkSet(linkSet, load) { console.assert(load.status == 'loading' || load.status == 'loaded', 'loading or loaded on link set'); for (var i = 0, l = linkSet.loads.length; i < l; i++) if (linkSet.loads[i] == load) return; linkSet.loads.push(load); load.linkSets.push(linkSet); // adjustment, see https://bugs.ecmascript.org/show_bug.cgi?id=2603 if (load.status != 'loaded') { linkSet.loadingCount++; } var loader = linkSet.loader; for (var i = 0, l = load.dependencies.length; i < l; i++) { var name = load.dependencies[i].value; if (loader.modules[name]) continue; for (var j = 0, d = loader.loads.length; j < d; j++) { if (loader.loads[j].name != name) continue; addLoadToLinkSet(linkSet, loader.loads[j]); break; } } // console.log('add to linkset ' + load.name); // snapshot(linkSet.loader); } // linking errors can be generic or load-specific // this is necessary for debugging info function doLink(linkSet) { var error = false; try { link(linkSet, function(load, exc) { linkSetFailed(linkSet, load, exc); error = true; }); } catch(e) { linkSetFailed(linkSet, null, e); error = true; } return error; } // 15.2.5.2.3 function updateLinkSetOnLoad(linkSet, load) { // console.log('update linkset on load ' + load.name); // snapshot(linkSet.loader); console.assert(load.status == 'loaded' || load.status == 'linked', 'loaded or linked'); linkSet.loadingCount--; if (linkSet.loadingCount > 0) return; // adjusted for spec bug https://bugs.ecmascript.org/show_bug.cgi?id=2995 var startingLoad = linkSet.startingLoad; // non-executing link variation for loader tracing // on the server. Not in spec. /***/ if (linkSet.loader.loaderObj.execute === false) { var loads = [].concat(linkSet.loads); for (var i = 0, l = loads.length; i < l; i++) { var load = loads[i]; load.module = !load.isDeclarative ? { module: _newModule({}) } : { name: load.name, module: _newModule({}), evaluated: true }; load.status = 'linked'; finishLoad(linkSet.loader, load); } return linkSet.resolve(startingLoad); } /***/ var abrupt = doLink(linkSet); if (abrupt) return; console.assert(linkSet.loads.length == 0, 'loads cleared'); linkSet.resolve(startingLoad); } // 15.2.5.2.4 function linkSetFailed(linkSet, load, exc) { var loader = linkSet.loader; if (load) { if (load && linkSet.loads[0].name != load.name) exc = addToError(exc, 'Error loading ' + load.name + ' from ' + linkSet.loads[0].name); if (load) exc = addToError(exc, 'Error loading ' + load.name); } else { exc = addToError(exc, 'Error linking ' + linkSet.loads[0].name); } var loads = linkSet.loads.concat([]); for (var i = 0, l = loads.length; i < l; i++) { var load = loads[i]; // store all failed load records loader.loaderObj.failed = loader.loaderObj.failed || []; if (indexOf.call(loader.loaderObj.failed, load) == -1) loader.loaderObj.failed.push(load); var linkIndex = indexOf.call(load.linkSets, linkSet); console.assert(linkIndex != -1, 'link not present'); load.linkSets.splice(linkIndex, 1); if (load.linkSets.length == 0) { var globalLoadsIndex = indexOf.call(linkSet.loader.loads, load); if (globalLoadsIndex != -1) linkSet.loader.loads.splice(globalLoadsIndex, 1); } } linkSet.reject(exc); } // 15.2.5.2.5 function finishLoad(loader, load) { // add to global trace if tracing if (loader.loaderObj.trace) { if (!loader.loaderObj.loads) loader.loaderObj.loads = {}; var depMap = {}; load.dependencies.forEach(function(dep) { depMap[dep.key] = dep.value; }); loader.loaderObj.loads[load.name] = { name: load.name, deps: load.dependencies.map(function(dep){ return dep.key }), depMap: depMap, address: load.address, metadata: load.metadata, source: load.source, kind: load.isDeclarative ? 'declarative' : 'dynamic' }; } // if not anonymous, add to the module table if (load.name) { console.assert(!loader.modules[load.name], 'load not in module table'); loader.modules[load.name] = load.module; } var loadIndex = indexOf.call(loader.loads, load); if (loadIndex != -1) loader.loads.splice(loadIndex, 1); for (var i = 0, l = load.linkSets.length; i < l; i++) { loadIndex = indexOf.call(load.linkSets[i].loads, load); if (loadIndex != -1) load.linkSets[i].loads.splice(loadIndex, 1); } load.linkSets.splice(0, load.linkSets.length); } function doDynamicExecute(linkSet, load, linkError) { try { var module = load.execute(); } catch(e) { linkError(load, e); return; } if (!module || !(module instanceof Module)) linkError(load, new TypeError('Execution must define a Module instance')); else return module; } // 26.3 Loader // 26.3.1.1 // defined at top // importPromises adds ability to import a module twice without error - https://bugs.ecmascript.org/show_bug.cgi?id=2601 function createImportPromise(loader, name, promise) { var importPromises = loader._loader.importPromises; return importPromises[name] = promise.then(function(m) { importPromises[name] = undefined; return m; }, function(e) { importPromises[name] = undefined; throw e; }); } Loader.prototype = { // 26.3.3.1 constructor: Loader, // 26.3.3.2 define: function(name, source, options) { // check if already defined if (this._loader.importPromises[name]) throw new TypeError('Module is already loading.'); return createImportPromise(this, name, new Promise(asyncStartLoadPartwayThrough({ step: 'translate', loader: this._loader, moduleName: name, moduleMetadata: options && options.metadata || {}, moduleSource: source, moduleAddress: options && options.address }))); }, // 26.3.3.3 'delete': function(name) { var loader = this._loader; delete loader.importPromises[name]; delete loader.moduleRecords[name]; return loader.modules[name] ? delete loader.modules[name] : false; }, // 26.3.3.4 entries not implemented // 26.3.3.5 get: function(key) { if (!this._loader.modules[key]) return; doEnsureEvaluated(this._loader.modules[key], [], this); return this._loader.modules[key].module; }, // 26.3.3.7 has: function(name) { return !!this._loader.modules[name]; }, // 26.3.3.8 'import': function(name, parentName, parentAddress) { if (typeof parentName == 'object') parentName = parentName.name; // run normalize first var loaderObj = this; // added, see https://bugs.ecmascript.org/show_bug.cgi?id=2659 return Promise.resolve(loaderObj.normalize(name, parentName)) .then(function(name) { var loader = loaderObj._loader; if (loader.modules[name]) { doEnsureEvaluated(loader.modules[name], [], loader._loader); return loader.modules[name].module; } return loader.importPromises[name] || createImportPromise(loaderObj, name, loadModule(loader, name, {}) .then(function(load) { delete loader.importPromises[name]; return evaluateLoadedModule(loader, load); })); }); }, // 26.3.3.9 keys not implemented // 26.3.3.10 load: function(name, options) { if (this._loader.modules[name]) { doEnsureEvaluated(this._loader.modules[name], [], this._loader); return Promise.resolve(this._loader.modules[name].module); } return this._loader.importPromises[name] || createImportPromise(this, name, loadModule(this._loader, name, {})); }, // 26.3.3.11 module: function(source, options) { var load = createLoad(); load.address = options && options.address; var linkSet = createLinkSet(this._loader, load); var sourcePromise = Promise.resolve(source); var loader = this._loader; var p = linkSet.done.then(function() { return evaluateLoadedModule(loader, load); }); proceedToTranslate(loader, load, sourcePromise); return p; }, // 26.3.3.12 newModule: function (obj) { if (typeof obj != 'object') throw new TypeError('Expected object'); // we do this to be able to tell if a module is a module privately in ES5 // by doing m instanceof Module var m = new Module(); var pNames; if (Object.getOwnPropertyNames && obj != null) { pNames = Object.getOwnPropertyNames(obj); } else { pNames = []; for (var key in obj) pNames.push(key); } for (var i = 0; i < pNames.length; i++) (function(key) { defineProperty(m, key, { configurable: false, enumerable: true, get: function () { return obj[key]; } }); })(pNames[i]); if (Object.preventExtensions) Object.preventExtensions(m); return m; }, // 26.3.3.14 set: function(name, module) { if (!(module instanceof Module)) throw new TypeError('Loader.set(' + name + ', module) must be a module'); this._loader.modules[name] = { module: module }; }, // 26.3.3.15 values not implemented // 26.3.3.16 @@iterator not implemented // 26.3.3.17 @@toStringTag not implemented // 26.3.3.18.1 normalize: function(name, referrerName, referrerAddress) { return name; }, // 26.3.3.18.2 locate: function(load) { return load.name; }, // 26.3.3.18.3 fetch: function(load) { }, // 26.3.3.18.4 translate: function(load) { return load.source; }, // 26.3.3.18.5 instantiate: function(load) { } }; var _newModule = Loader.prototype.newModule; /* * ES6 Module Declarative Linking Code - Dev Build Only */ function link(linkSet, linkError) { var loader = linkSet.loader; if (!linkSet.loads.length) return; var loads = linkSet.loads.concat([]); for (var i = 0; i < loads.length; i++) { var load = loads[i]; var module = doDynamicExecute(linkSet, load, linkError); if (!module) return; load.module = { name: load.name, module: module }; load.status = 'linked'; finishLoad(loader, load); } } function evaluateLoadedModule(loader, load) { console.assert(load.status == 'linked', 'is linked ' + load.name); return load.module.module; } function doEnsureEvaluated() {} })();/* ********************************************************************************************* System Loader Implementation - Implemented to https://github.com/jorendorff/js-loaders/blob/master/browser-loader.js - <script type="module"> supported ********************************************************************************************* */ var System; function SystemLoader() { Loader.call(this); this.paths = {}; } // NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25 function applyPaths(paths, name) { // most specific (most number of slashes in path) match wins var pathMatch = '', wildcard, maxSlashCount = 0; // check to see if we have a paths entry for (var p in paths) { var pathParts = p.split('*'); if (pathParts.length > 2) throw new TypeError('Only one wildcard in a path is permitted'); // exact path match if (pathParts.length == 1) { if (name == p) { pathMatch = p; break; } } // wildcard path match else { var slashCount = p.split('/').length; if (slashCount >= maxSlashCount && name.substr(0, pathParts[0].length) == pathParts[0] && name.substr(name.length - pathParts[1].length) == pathParts[1]) { maxSlashCount = slashCount; pathMatch = p; wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length); } } } var outPath = paths[pathMatch] || name; if (wildcard) outPath = outPath.replace('*', wildcard); return outPath; } // inline Object.create-style class extension function LoaderProto() {} LoaderProto.prototype = Loader.prototype; SystemLoader.prototype = new LoaderProto(); var absURLRegEx = /^([^\/]+:\/\/|\/)/; // Normalization with module names as absolute URLs SystemLoader.prototype.normalize = function(name, parentName, parentAddress) { // NB does `import 'file.js'` import relative to the parent name or baseURL? // have assumed that it is baseURL-relative here, but spec may well align with URLs to be the latter // safe option for users is to always use "./file.js" for relative // not absolute or relative -> apply paths (what will be sites) if (!name.match(absURLRegEx) && name[0] != '.') name = new URL(applyPaths(this.paths, name), baseURI).href; // apply parent-relative normalization, parentAddress is already normalized else name = new URL(name, parentName || baseURI).href; return name; }; SystemLoader.prototype.locate = function(load) { return load.name; }; // ensure the transpiler is loaded correctly SystemLoader.prototype.instantiate = function(load) { var self = this; return Promise.resolve(self.normalize(self.transpiler)) .then(function(transpilerNormalized) { // load transpiler as a global (avoiding System clobbering) if (load.address === transpilerNormalized) { return { deps: [], execute: function() { var curSystem = __global.System; var curLoader = __global.Reflect.Loader; // ensure not detected as CommonJS __eval('(function(require,exports,module){' + load.source + '})();', load.address, __global); __global.System = curSystem; __global.Reflect.Loader = curLoader; return self.newModule({ 'default': __global[self.transpiler], __useDefault: true }); } }; } }); };// SystemJS Loader Class and Extension helpers function SystemJSLoader() { SystemLoader.call(this); systemJSConstructor.call(this); } // inline Object.create-style class extension function SystemProto() {}; SystemProto.prototype = SystemLoader.prototype; SystemJSLoader.prototype = new SystemProto(); var systemJSConstructor; function hook(name, hook) { SystemJSLoader.prototype[name] = hook(SystemJSLoader.prototype[name]); } function hookConstructor(hook) { systemJSConstructor = hook(systemJSConstructor || function() {}); } function dedupe(deps) { var newDeps = []; for (var i = 0, l = deps.length; i < l; i++) if (indexOf.call(newDeps, deps[i]) == -1) newDeps.push(deps[i]) return newDeps; } function extend(a, b, underwrite) { for (var p in b) { if (!underwrite || !(p in a)) a[p] = b[p]; } }/* * Script tag fetch * * When load.metadata.scriptLoad is true, we load via script tag injection. */ (function() { if (typeof document != 'undefined') var head = document.getElementsByTagName('head')[0]; // call this functione everytime a wrapper executes var curSystem; // System clobbering protection for Traceur SystemJSLoader.prototype.onScriptLoad = function() { __global.System = curSystem; }; function webWorkerImport(loader, load) { return new Promise(function(resolve, reject) { try { importScripts(load.address); } catch(e) { reject(e); } loader.onScriptLoad(load); // if nothing registered, then something went wrong if (!load.metadata.registered) reject(load.address + ' did not call System.register or AMD define'); resolve(''); }); } // override fetch to use script injection hook('fetch', function(fetch) { return function(load) { var loader = this; if (!load.metadata.scriptLoad || (!isBrowser && !isWorker)) return fetch.call(this, load); if (isWorker) return webWorkerImport(loader, load); return new Promise(function(resolve, reject) { var s = document.createElement('script'); s.async = true; function complete(evt) { if (s.readyState && s.readyState != 'loaded' && s.readyState != 'complete') return; cleanup(); // this runs synchronously after execution // we now need to tell the wrapper handlers that // this load record has just executed loader.onScriptLoad(load); // if nothing registered, then something went wrong if (!load.metadata.registered) reject(load.address + ' did not call System.register or AMD define'); resolve(''); } function error(evt) { cleanup(); reject(new Error('Unable to load script ' + load.address)); } if (s.attachEvent) { s.attachEvent('onreadystatechange', complete); } else { s.addEventListener('load', complete, false); s.addEventListener('error', error, false); } curSystem = __global.System; __global.System = loader; s.src = load.address; head.appendChild(s); function cleanup() { if (s.detachEvent) s.detachEvent('onreadystatechange', complete); else { s.removeEventListener('load', complete, false); s.removeEventListener('error', error, false); } head.removeChild(s); } }); }; }); })(); /* * Script-only addition used for production loader * */ hook('fetch', function(fetch) { return function(load) { load.metadata.scriptLoad = true; // prepare amd define this.get('@@amd-helpers').createDefine(this); return fetch.call(this, load); }; }); // AMD support // script injection mode calls this function synchronously on load hook('onScriptLoad', function(onScriptLoad) { return function(load) { onScriptLoad.call(this, load); var lastModule = this.get('@@amd-helpers').lastModule; if (lastModule.anonDefine || lastModule.isBundle) { load.metadata.format = 'defined'; load.metadata.registered = true; lastModule.isBundle = false; } if (lastModule.anonDefine) { load.metadata.deps = load.metadata.deps ? load.metadata.deps.concat(lastModule.anonDefine.deps) : lastModule.anonDefine.deps; load.metadata.execute = lastModule.anonDefine.execute; lastModule.anonDefine = null; } }; });/* * Instantiate registry extension * * Supports Traceur System.register 'instantiate' output for loading ES6 as ES5. * * - Creates the loader.register function * - Also supports metadata.format = 'register' in instantiate for anonymous register modules * - Also supports metadata.deps, metadata.execute and metadata.executingRequire * for handling dynamic modules alongside register-transformed ES6 modules * * * The code here replicates the ES6 linking groups algorithm to ensure that * circular ES6 compiled into System.register can work alongside circular AMD * and CommonJS, identically to the actual ES6 loader. * */ (function() { /* * There are two variations of System.register: * 1. System.register for ES6 conversion (2-3 params) - System.register([name, ]deps, declare) * see https://github.com/ModuleLoader/es6-module-loader/wiki/System.register-Explained * * 2. System.registerDynamic for dynamic modules (3-4 params) - System.registerDynamic([name, ]deps, executingRequire, execute) * the true or false statement * * this extension implements the linking algorithm for the two variations identical to the spec * allowing compiled ES6 circular references to work alongside AMD and CJS circular references. * */ var anonRegister; var calledRegister; function doRegister(loader, name, register) { calledRegister = true; // named register if (name) { name = loader.normalizeSync(name); register.name = name; if (!(name in loader.defined)) loader.defined[name] = register; } // anonymous register else if (register.declarative) { if (anonRegister) throw new TypeError('Multiple anonymous System.register calls in the same module file.'); anonRegister = register; } } SystemJSLoader.prototype.register = function(name, deps, declare) { if (typeof name != 'string') { declare = deps; deps = name; name = null; } // dynamic backwards-compatibility // can be deprecated eventually if (typeof declare == 'boolean') return this.registerDynamic.apply(this, arguments); doRegister(this, name, { declarative: true, deps: deps, declare: declare }); }; SystemJSLoader.prototype.registerDynamic = function(name, deps, declare, execute) { if (typeof name != 'string') { execute = declare; declare = deps; deps = name; name = null; } // dynamic doRegister(this, name, { declarative: false, deps: deps, execute: execute, executingRequire: declare }); }; /* * Registry side table - loader.defined * Registry Entry Contains: * - name * - deps * - declare for declarative modules * - execute for dynamic modules, different to declarative execute on module * - executingRequire indicates require drives execution for circularity of dynamic modules * - declarative optional boolean indicating which of the above * * Can preload modules directly on System.defined['my/module'] = { deps, execute, executingRequire } * * Then the entry gets populated with derived information during processing: * - normalizedDeps derived from deps, created in instantiate * - groupIndex used by group linking algorithm * - evaluated indicating whether evaluation has happend * - module the module record object, containing: * - exports actual module exports * * For dynamic we track the es module with: * - esModule actual es module value * * Then for declarative only we track dynamic bindings with the 'module' records: * - name * - exports * - setters declarative setter functions * - dependencies, module records of dependencies * - importers, module records of dependents * * After linked and evaluated, entries are removed, declarative module records remain in separate * module binding table * */ hookConstructor(function(constructor) { return function() { constructor.call(this); this.defined = {}; this._loader.moduleRecords = {}; }; }); // script injection mode calls this function synchronously on load hook('onScriptLoad', function(onScriptLoad) { return function(load) { onScriptLoad.call(this, load); // anonymous define if (anonRegister) load.metadata.entry = anonRegister; if (calledRegister) { load.metadata.format = load.metadata.format || 'defined'; load.metadata.registered = true; calledRegister = false; anonRegister = null; } }; }); function buildGroups(entry, loader, groups) { groups[entry.groupIndex] = groups[entry.groupIndex] || []; if (indexOf.call(groups[entry.groupIndex], entry) != -1) return; groups[entry.groupIndex].push(entry); for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) { var depName = entry.normalizedDeps[i]; var depEntry = loader.defined[depName]; // not in the registry means already linked / ES6 if (!depEntry || depEntry.evaluated) continue; // now we know the entry is in our unlinked linkage group var depGroupIndex = entry.groupIndex + (depEntry.declarative != entry.declarative); // the group index of an entry is always the maximum if (depEntry.groupIndex === undefined || depEntry.groupIndex < depGroupIndex) { // if already in a group, remove from the old group if (depEntry.groupIndex !== undefined) { groups[depEntry.groupIndex].splice(indexOf.call(groups[depEntry.groupIndex], depEntry), 1); // if the old group is empty, then we have a mixed depndency cycle if (groups[depEntry.groupIndex].length == 0) throw new TypeError("Mixed dependency cycle detected"); } depEntry.groupIndex = depGroupIndex; } buildGroups(depEntry, loader, groups); } } function link(name, loader) { var startEntry = loader.defined[name]; // skip if already linked if (startEntry.module) return; startEntry.groupIndex = 0; var groups = []; buildGroups(startEntry, loader, groups); var curGroupDeclarative = !!startEntry.declarative == groups.length % 2; for (var i = groups.length - 1; i >= 0; i--) { var group = groups[i]; for (var j = 0; j < group.length; j++) { var entry = group[j]; // link each group if (curGroupDeclarative) linkDeclarativeModule(entry, loader); else linkDynamicModule(entry, loader); } curGroupDeclarative = !curGroupDeclarative; } } // module binding records function getOrCreateModuleRecord(name, moduleRecords) { return moduleRecords[name] || (moduleRecords[name] = { name: name, dependencies: [], exports: {}, // start from an empty module and extend importers: [] }); } function linkDeclarativeModule(entry, loader) { // only link if already not already started linking (stops at circular) if (entry.module) return; var moduleRecords = loader._loader.moduleRecords; var module = entry.module = getOrCreateModuleRecord(entry.name, moduleRecords); var exports = entry.module.exports; var declaration = entry.declare.call(__global, function(name, value) { module.locked = true; if (typeof name == 'object') { for (var p in name) exports[p] = name[p]; } else { exports[name] = value; } for (var i = 0, l = module.importers.length; i < l; i++) { var importerModule = module.importers[i]; if (!importerModule.locked) { var importerIndex = indexOf.call(importerModule.dependencies, module); importerModule.setters[importerIndex](exports); } } module.locked = false; return value; }); module.setters = declaration.setters; module.execute = declaration.execute; if (!module.setters || !module.execute) { throw new TypeError('Invalid System.register form for ' + entry.name); } // now link all the module dependencies for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) { var depName = entry.normalizedDeps[i]; var depEntry = loader.defined[depName]; var depModule = moduleRecords[depName]; // work out how to set depExports based on scenarios... var depExports; if (depModule) { depExports = depModule.exports; } // dynamic, already linked in our registry else if (depEntry && !depEntry.declarative) { depExports = depEntry.esModule; } // in the loader registry else if (!depEntry) { depExports = loader.get(depName); } // we have an entry -> link else { linkDeclarativeModule(depEntry, loader); depModule = depEntry.module; depExports = depModule.exports; } // only declarative modules have dynamic bindings if (depModule && depModule.importers) { depModule.importers.push(module); module.dependencies.push(depModule); } else { module.dependencies.push(null); } // run the setter for this dependency if (module.setters[i]) module.setters[i](depExports); } } // An analog to loader.get covering execution of all three layers (real declarative, simulated declarative, simulated dynamic) function getModule(name, loader) { var exports; var entry = loader.defined[name]; if (!entry) { exports = loader.get(name); if (!exports) throw new Error('Unable to load dependency ' + name + '.'); } else { if (entry.declarative) ensureEvaluated(name, [], loader); else if (!entry.evaluated) linkDynamicModule(entry, loader); exports = entry.module.exports; } if ((!entry || entry.declarative) && exports && exports.__useDefault) return exports['default']; return exports; } function linkDynamicModule(entry, loader) { if (entry.module) return; var exports = {}; var module = entry.module = { exports: exports, id: entry.name }; // AMD requires execute the tree first if (!entry.executingRequire) { for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) { var depName = entry.normalizedDeps[i]; // we know we only need to link dynamic due to linking algorithm var depEntry = loader.defined[depName]; if (depEntry) linkDynamicModule(depEntry, loader); } } // now execute entry.evaluated = true; var output = entry.execute.call(__global, function(name) { for (var i = 0, l = entry.deps.length; i < l; i++) { if (entry.deps[i] != name) continue; return getModule(entry.normalizedDeps[i], loader); } throw new TypeError('Module ' + name + ' not declared as a dependency.'); }, exports, module); if (output) module.exports = output; // create the esModule object, which allows ES6 named imports of dynamics exports = module.exports; if (exports && exports.__esModule) { entry.esModule = exports; } else { var hasOwnProperty = exports && exports.hasOwnProperty; entry.esModule = {}; for (var p in exports) { if (!hasOwnProperty || exports.hasOwnProperty(p)) entry.esModule[p] = exports[p]; } entry.esModule['default'] = exports; defineProperty(entry.esModule, '__useDefault', { value: true }); } } /* * Given a module, and the list of modules for this current branch, * ensure that each of the dependencies of this module is evaluated * (unless one is a circular dependency already in the list of seen * modules, in which case we execute it) * * Then we evaluate the module itself depth-first left to right * execution to match ES6 modules */ function ensureEvaluated(moduleName, seen, loader) { var entry = loader.defined[moduleName]; // if already seen, that means it's an already-evaluated non circular dependency if (!entry || entry.evaluated || !entry.declarative) return; // this only applies to declarative modules which late-execute seen.push(moduleName); for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) { var depName = entry.normalizedDeps[i]; if (indexOf.call(seen, depName) == -1) { if (!loader.defined[depName]) loader.get(depName); else ensureEvaluated(depName, seen, loader); } } if (entry.evaluated) return; entry.evaluated = true; entry.module.execute.call(__global); } // override the delete method to also clear the register caches hook('delete', function(del) { return function(name) { delete this._loader.moduleRecords[name]; delete this.defined[name]; return del.call(this, name); }; }); var registerRegEx = /^\s*(\/\*.*\*\/\s*|\/\/[^\n]*\s*)*System\.register(Dyanmic)?\s*\(/; hook('fetch', function(fetch) { return function(load) { if (this.defined[load.name]) { load.metadata.format = 'defined'; return ''; } // this is the synchronous chain for onScriptLoad anonRegister = null; calledRegister = false; if (load.metadata.format == 'register') load.metadata.scriptLoad = true; // NB remove when "deps " is deprecated load.metadata.deps = load.metadata.deps || []; return fetch.call(this, load); }; }); hook('translate', function(translate) { // we run the meta detection here (register is after meta) return function(load) { return Promise.resolve(translate.call(this, load)).then(function(source) { if (typeof load.metadata.deps === 'string') load.metadata.deps = load.metadata.deps.split(','); load.metadata.deps = load.metadata.deps || []; // run detection for register format if (load.metadata.format == 'register' || !load.metadata.format && load.source.match(registerRegEx)) load.metadata.format = 'register'; return source; }); }; }); hook('instantiate', function(instantiate) { return function(load) { var loader = this; var entry; // first we check if this module has already been defined in the registry if (loader.defined[load.name]) { entry = loader.defined[load.name]; entry.deps = entry.deps.concat(load.metadata.deps); } // picked up already by a script injection else if (load.metadata.entry) entry = load.metadata.entry; // otherwise check if it is dynamic else if (load.metadata.execute) { entry = { declarative: false, deps: load.metadata.deps || [], execute: load.metadata.execute, executingRequire: load.metadata.executingRequire // NodeJS-style requires or not }; } // Contains System.register calls else if (load.metadata.format == 'register' || load.metadata.format == 'esm' || load.metadata.format == 'es6') { anonRegister = null; calledRegister = false; __exec.call(loader, load); if (anonRegister) entry = anonRegister; else load.metadata.bundle = true; if (!entry && loader.defined[load.name]) entry = loader.defined[load.name]; if (!calledRegister && !load.metadata.registered) throw new TypeError(load.name + ' detected