UNPKG

steal

Version:
1,592 lines (1,368 loc) 70.9 kB
(function(__global) { var isWorker = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; var isBrowser = typeof window != 'undefined' && !isWorker; __global.$__Object$getPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; }; var $__Object$defineProperty; (function () { try { if (!!Object.defineProperty({}, 'a', {})) { $__Object$defineProperty = Object.defineProperty; } } catch (e) { $__Object$defineProperty = function (obj, prop, opt) { try { obj[prop] = opt.value || opt.get.call(obj); } catch(e) {} } } }()); __global.$__Object$create = Object.create || function(o, props) { function F() {} F.prototype = o; if (typeof(props) === "object") { for (prop in props) { if (props.hasOwnProperty((prop))) { F[prop] = props[prop]; } } } return new F(); }; var $__Object$defineProperties = Object.defineProperties; var $__Object$defineProperty0 = Object.defineProperty; var $__Object$create = Object.create; var $__Object$getPrototypeOf = Object.getPrototypeOf; (function() { var Promise = __global.Promise || require("when/es6-shim/Promise"); var console; var $__curScript; if (__global.console) { console = __global.console; console.assert = console.assert || function() {}; } else { console = { assert: function() {} }; } if(isBrowser) { var scripts = document.getElementsByTagName("script"); $__curScript = document.currentScript || scripts[scripts.length - 1]; } // 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 = $__Object$defineProperty; var emptyArray = []; // 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)); }) .then(function(name) { return Promise.resolve(loader.loaderObj.notifyLoad(request, name, refererName)) .then(function() { return name; }); }) // 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; } var failedLoads = loader.loaderObj.failed || emptyArray; for(var i = 0, l = failedLoads.length; i < l; i++) { load = failedLoads[i]; if(load.name !== name) continue; return Promise.reject("The load " + name + " already failed."); } 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) { var pass = load.pass || 0; var passCancelled = function() { return (load.pass << 0) !== pass ; }; 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) { if(load.status != "loading" || passCancelled()) { return; } 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(load.status != "loading" || passCancelled()) { return; } if (instantiateResult === undefined) { load.address = load.address || "<Anonymous Module " + ++anonCnt + ">"; // instead of load.kind, use load.isDeclarative load.isDeclarative = true; return loader.loaderObj.transpile(load) .then(function(transpiled) { // Hijack System.register to set declare function var curSystem = __global.System; var curRegister = curSystem.register; curSystem.register = function(name, regDeps, regDeclare) { var declare = regDeclare; var deps = regDeps; if (typeof name != "string") { declare = deps; deps = name; } load.declare = declare; load.depsList = deps; }; __eval(transpiled, __global, load); 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() { if(load.status != "loading" || passCancelled()) { return; } load.dependencies = []; var depsList = load.depsList; var loadPromises = []; function loadDep(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 }; // console.log('AddDependencyLoad ' + depLoad.name + ' for ' + load.name); // snapshot(loader); if (depLoad.status != "linked") { var linkSets = load.linkSets.concat([]); for (var i = 0, l = linkSets.length; i < l; i++) addLoadToLinkSet(linkSets[i], depLoad); } }) ); } for (var i = 0, l = depsList.length; i < l; i++) { loadDep(depsList[i], i); } return Promise.all(loadPromises); }) // 15.2.4.6.2 LoadSucceeded .then(function() { // console.log('LoadSucceeded ' + load.name); // snapshot(loader); if(load.status != "loading" || passCancelled()) { return; } 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 function incrementPass(load) { load.pass = load.pass != null ? (load.pass + 1) : 1; } function changeLoadingStatus(load, newStatus) { var oldStatus = load.status; load.status = newStatus; if(newStatus !== oldStatus && oldStatus === "loaded") { load.linkSets.forEach(function(linkSet){ linkSet.loadingCount++; }); } } // 15.2.4.7.1 function asyncStartLoadPartwayThrough(stepState) { return function(resolve, reject) { var loader = stepState.loader; var name = stepState.moduleName; var step = stepState.step; var importingModuleName = stepState.moduleMetadata.importingModuleName; if (loader.modules[name]) throw new TypeError("\"" + name + "\" already exists in the module table"); // adjusted to pick up existing loads var existingLoad, firstLinkSet; 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)); } // If the module importing this is part of the same linkSet, create // a new one for this import. firstLinkSet = existingLoad.linkSets[0]; if(importingModuleName && firstLinkSet.loads[importingModuleName]) { continue; } return firstLinkSet.done.then(function() { resolve(existingLoad); }); } } var load; if(existingLoad) { load = existingLoad; } else { load = createLoad(name); load.metadata = stepState.moduleMetadata; } var linkSet = createLinkSet(loader, load); if(!existingLoad) { 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" || load.status === "failed", "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); linkSet.loads[load.name] = true; 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; // console.log('add to linkset ' + load.name); // snapshot(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; } } } // 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, linkExc) { var loader = linkSet.loader; var exc = linkExc; /* if (linkSet.loads[0].name != load.name) exc = addToError(exc, 'Error loading "' + load.name + '" from "' + linkSet.loads[0].name + '" at ' + (linkSet.loads[0].address || '<unknown>') + '\n'); exc = addToError(exc, 'Error loading "' + load.name + '" at ' + (load.address || '<unknown>') + '\n'); */ 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 (load.status === "failed" && indexOf.call(loader.loaderObj.failed, load) == -1) loader.loaderObj.failed.push(load); else if(loader.loaderObj._pendingState) loader.loaderObj._pendingState(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); } // 15.2.5.3 Module Linking Groups // 15.2.5.3.2 BuildLinkageGroups alternative implementation // Adjustments (also see https://bugs.ecmascript.org/show_bug.cgi?id=2755) // 1. groups is an already-interleaved array of group kinds // 2. load.groupIndex is set when this function runs // 3. load.groupIndex is the interleaved index ie 0 declarative, 1 dynamic, 2 declarative, ... (or starting with dynamic) function buildLinkageGroups(load, loads, groups) { groups[load.groupIndex] = groups[load.groupIndex] || []; // if the load already has a group index and its in its group, its already been done // this logic naturally handles cycles if (indexOf.call(groups[load.groupIndex], load) != -1) return; // now add it to the group to indicate its been seen groups[load.groupIndex].push(load); for (var i = 0, l = loads.length; i < l; i++) { var loadDep = loads[i]; // dependencies not found are already linked for (var j = 0; j < load.dependencies.length; j++) { if (loadDep.name == load.dependencies[j].value) { // by definition all loads in linkset are loaded, not linked console.assert(loadDep.status == "loaded", "Load in linkSet not loaded!"); // if it is a group transition, the index of the dependency has gone up // otherwise it is the same as the parent var loadDepGroupIndex = load.groupIndex + (loadDep.isDeclarative != load.isDeclarative); // the group index of an entry is always the maximum if (loadDep.groupIndex === undefined || loadDep.groupIndex < loadDepGroupIndex) { // if already in a group, remove from the old group if (loadDep.groupIndex !== undefined) { groups[loadDep.groupIndex].splice(indexOf.call(groups[loadDep.groupIndex], loadDep), 1); // if the old group is empty, then we have a mixed depndency cycle if (groups[loadDep.groupIndex].length == 0) throw new TypeError("Mixed dependency cycle detected"); } loadDep.groupIndex = loadDepGroupIndex; } buildLinkageGroups(loadDep, loads, groups); } } } } 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; } // 15.2.5.4 function link(linkSet, linkError) { var loader = linkSet.loader; if (!linkSet.loads.length) return; // console.log('linking {' + logloads(linkSet.loads) + '}'); // snapshot(loader); // 15.2.5.3.1 LinkageGroups alternative implementation // build all the groups // because the first load represents the top of the tree // for a given linkset, we can work down from there var groups = []; var startingLoad = linkSet.loads[0]; startingLoad.groupIndex = 0; buildLinkageGroups(startingLoad, linkSet.loads, groups); // determine the kind of the bottom group var curGroupDeclarative = startingLoad.isDeclarative == groups.length % 2; // run through the groups from bottom to top for (var i = groups.length - 1; i >= 0; i--) { var group = groups[i]; for (var j = 0; j < group.length; j++) { var load = group[j]; // 15.2.5.5 LinkDeclarativeModules adjusted if (curGroupDeclarative) { linkDeclarativeModule(load, linkSet.loads, loader); } // 15.2.5.6 LinkDynamicModules adjusted else { var module = doDynamicExecute(linkSet, load, linkError); if (!module) return; load.module = { name: load.name, module: module }; load.status = "linked"; } finishLoad(loader, load); } // alternative current kind for next loop curGroupDeclarative = !curGroupDeclarative; } } // custom module records for binding graph // store linking module records in a separate table function getOrCreateModuleRecord(name, loader) { var moduleRecords = loader.moduleRecords; return moduleRecords[name] || (moduleRecords[name] = { name: name, dependencies: [], module: new Module(), // start from an empty module and extend importers: [] }); } // custom declarative linking function function linkDeclarativeModule(load, loads, loader) { if (load.module) return; var module = load.module = getOrCreateModuleRecord(load.name, loader); var moduleObj = load.module.module; var registryEntry = load.declare.call(__global, function(name, value) { // NB This should be an Object.defineProperty, but that is very slow. // By disaling this module write-protection we gain performance. // It could be useful to allow an option to enable or disable this. module.locked = true; if(typeof name === "object") { for(var p in name) { moduleObj[p] = name[p]; } } else { moduleObj[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](moduleObj); } } module.locked = false; return value; }); // setup our setters and execution function module.setters = registryEntry.setters; module.execute = registryEntry.execute; // now link all the module dependencies // amending the depMap as we go for (var i = 0, l = load.dependencies.length; i < l; i++) { var depName = load.dependencies[i].value; var depModule = loader.modules[depName]; // if dependency not already in the module registry // then try and link it now if (!depModule) { // get the dependency load record for (var j = 0; j < loads.length; j++) { if (loads[j].name != depName) continue; // only link if already not already started linking (stops at circular / dynamic) if (!loads[j].module) { linkDeclarativeModule(loads[j], loads, loader); depModule = loads[j].module; } // if circular, create the module record else { depModule = getOrCreateModuleRecord(depName, loader); } } } // only declarative modules have dynamic bindings if (depModule.importers) { module.dependencies.push(depModule); depModule.importers.push(module); } else { // track dynamic records as null module records as already linked module.dependencies.push(null); } // run the setter for this dependency if (module.setters[i]) module.setters[i](depModule.module); } load.status = "linked"; } // 15.2.5.5.1 LinkImports not implemented // 15.2.5.7 ResolveExportEntries not implemented // 15.2.5.8 ResolveExports not implemented // 15.2.5.9 ResolveExport not implemented // 15.2.5.10 ResolveImportEntries not implemented // 15.2.6.1 function evaluateLoadedModule(loader, load) { console.assert(load.status == "linked", "is linked " + load.name); doEnsureEvaluated(load.module, [], loader); return load.module.module; } /* * Module Object non-exotic for ES5: * * module.module bound module object * module.execute execution function for module * module.dependencies list of module objects for dependencies * See getOrCreateModuleRecord for all properties * */ function doExecute(module, loader) { try { module.execute.call(__global); } catch(e) { e.onModuleExecution = true; cleanupStack(e); return e; } } function cleanupStack(err) { if (!err.originalErr) { var stack = (err.stack || err.message || err).toString().split("\n"); var newStack = []; for (var i = 0; i < stack.length; i++) { if (typeof $__curScript == "undefined" || stack[i].indexOf($__curScript.src) == -1) newStack.push(stack[i]); } if(newStack.length) { err.stack = newStack.join("\n\t"); } } return err; } // propogate execution errors // see https://bugs.ecmascript.org/show_bug.cgi?id=2993 function doEnsureEvaluated(module, seen, loader) { var err = ensureEvaluated(module, seen, loader); if (err) throw err; } // 15.2.6.2 EnsureEvaluated adjusted function ensureEvaluated(module, seen, loader) { if (module.evaluated || !module.dependencies) return; seen.push(module); var deps = module.dependencies; var err; for (var i = 0, l = deps.length; i < l; i++) { var dep = deps[i]; // dynamic dependencies are empty in module.dependencies // as they are already linked if (!dep) continue; if (indexOf.call(seen, dep) == -1) { err = ensureEvaluated(dep, seen, loader); // stop on error, see https://bugs.ecmascript.org/show_bug.cgi?id=2996 if (err) { err = addToError(err, "Error evaluating " + dep.name + "\n"); return err; } } } if (module.failed) return new Error("Module failed execution."); if (module.evaluated) return; module.evaluated = true; err = doExecute(module, loader); if (err) { module.failed = true; } else if (Object.preventExtensions) { // spec variation // we don't create a new module here because it was created and ammended // we just disable further extensions instead Object.preventExtensions(module.module); } module.execute = undefined; return err; } function addToError(error, msg) { var err = error; if (err instanceof Error) err.message = msg + err.message; else err = msg + err; return err; } // 26.3 Loader // 26.3.1.1 function Loader(options) { if (typeof options != "object") throw new TypeError("Options must be an object"); if (options.normalize) this.normalize = options.normalize; if (options.locate) this.locate = options.locate; if (options.fetch) this.fetch = options.fetch; if (options.translate) this.translate = options.translate; if (options.instantiate) this.instantiate = options.instantiate; this._loader = { loaderObj: this, loads: [], modules: {}, importPromises: {}, moduleRecords: {} }; // 26.3.3.6 // 26.3.3.13 realm not implemented defineProperty(this, "global", { get: function() { return __global; } }); } function Module() {} // 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, anonymousCount: 0, // 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]; if(this.failed) { var load; for(var i = 0; i < this.failed.length; i++) { load = this.failed[i]; if(load.name === name) { this.failed.splice(i, 1); break; } } } 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, options) { // run normalize first var loaderObj = this; // added, see https://bugs.ecmascript.org/show_bug.cgi?id=2659 return Promise.resolve(loaderObj.normalize(name, options && options.name, options && options.address)) .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, options || {}) .then(function(load) { delete loader.importPromises[name]; return evaluateLoadedModule(loader, load); }) .then(null, function(err){ if(loaderObj.defined) { loaderObj.defined[name] = undefined; } if(err.onModuleExecution && loaderObj.getModuleLoad) { var load = loaderObj.getModuleLoad(name); if(load) { return loaderObj.rejectWithCodeFrame(err, load); } } else if(err.promise) { return err.promise; } return Promise.reject(err); })); }); }, // 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 name = "<Anonymous" + (++this.anonymousCount) + ">"; var load = createLoad(name); 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) { throw new TypeError("Fetch not implemented"); }, // 26.3.3.18.4 translate: function(load) { return load.source; }, // 26.3.3.18.5 instantiate: function(load) {}, notifyLoad: function(specifier, name, parentName) {}, provide: function(name, source, options) { var load; for(var i = 0; i < this._loader.loads.length; i++) { if(this._loader.loads[i].name === name) { load = this._loader.loads[i]; break; } } if(load) { incrementPass(load); changeLoadingStatus(load, "loading"); return proceedToTranslate(this._loader, load, Promise.resolve(source)); } else { this["delete"](name); } return this.define(name, source, options); } }; var _newModule = Loader.prototype.newModule; if (typeof exports === "object") module.exports = Loader; __global.Reflect = __global.Reflect || {}; __global.Reflect.Loader = __global.Reflect.Loader || Loader; __global.Reflect.global = __global.Reflect.global || __global; __global.LoaderPolyfill = Loader; })(); (function(Loader) { var g = __global; var isNode = typeof self === "undefined" && typeof process !== "undefined" && {}.toString.call(process) === "[object process]"; function getTranspilerModule(loader, globalName) { return loader.newModule({ __useDefault: true, "default": g[globalName] }); } function getTranspilerGlobalName(loadName) { return loadName === "babel" ? "Babel" : loadName; } // Use Babel by default Loader.prototype.transpiler = "babel"; Loader.prototype.transpile = function(load) { var self = this; // pick up Transpiler modules from existing globals on first run if set if (!self.transpilerHasRun) { if (g.traceur && !self.has("traceur")) { self.set("traceur", getTranspilerModule(self, "traceur")); } if (g.Babel && !self.has("babel")) { self.set("babel", getTranspilerModule(self, "Babel")); } self.transpilerHasRun = true; } return self["import"](self.transpiler) .then(function(transpilerMod) { var transpiler = transpilerMod; if (transpiler.__useDefault) { transpiler = transpiler["default"]; } return (transpiler.Compiler ? traceurTranspile : babelTranspile) .call(self, load, transpiler); }) .then(function(code) { return "var __moduleAddress = \"" + load.address + "\";" + code; }); }; Loader.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.name === transpilerNormalized) { return { deps: [], execute: function() { var curSystem = g.System; var curLoader = g.Reflect.Loader; // ensure not detected as CommonJS __eval("(function(require,exports,module){" + load.source + "})();", g, load); g.System = curSystem; g.Reflect.Loader = curLoader; return getTranspilerModule(self, getTranspilerGlobalName(load.name)); } }; } }); }; function traceurTranspile(load, traceur) { var options = this.traceurOptions || {}; options.modules = "instantiate"; options.script = false; options.sourceMaps = "inline"; options.filename = load.address; options.inputSourceMap = load.metadata.sourceMap; options.moduleName = false; var compiler = new traceur.Compiler(options); var source = doTraceurCompile(load.source, compiler, options.filename); // add "!eval" to end of Traceur sourceURL // I believe this does something? source += "!eval"; return source; } function doTraceurCompile(source, compiler, filename) { try { return compiler.compile(source, filename); } catch(e) { throw e[0]; } } /** * Gets the babel environment name * return {string} The babel environment name */ function getBabelEnv() { var loader = this; var defaultEnv = "development"; var loaderEnv = typeof loader.getEnv === "function" && loader.getEnv(); if (isNode) { return process.env.BABEL_ENV || process.env.NODE_ENV || loaderEnv || defaultEnv; } else { return loaderEnv || defaultEnv; } } /** * Gets the babel preset or plugin name * @param {BabelPreset|BabelPlugin} presetOrPlugin A babel plugin or preset * @return {?string} The preset/plugin name */ function getPresetOrPluginName(presetOrPlugin) { if (includesPresetOrPluginName(presetOrPlugin)) { return typeof presetOrPlugin === "string" ? presetOrPlugin : presetOrPlugin[0]; } else { return null; } } /** * Whether the babel plugin/preset name was provided * * @param {BabelPreset|BabelPlugin} presetOrPlugin * @return {boolean} */ function includesPresetOrPluginName(presetOrPlugin) { return typeof presetOrPlugin === "string" || presetOrPlugin.length && typeof presetOrPlugin[0] === "string"; } /** * A Babel plugins as defined in `babelOptions.plugins` * @typedef {string|Function|<string, Object>[]|<Function, Object>[]} BabelPlugin */ var processBabelPlugins = (function() { /** * Returns a list of babel plugins to be used during transpilation * * Collects the babel plugins defined in `babelOptions.plugins` plus * the environment dependant plugins. * * @param {Object} babel The babel object exported by babel-standalone * @param {babelOptions} babelOptions The babel configuration object * @return {Promise.<BabelPlugin[]>} Promise that resolves to a list of babel plugins */ return function processBabelPlugins(babel, babelOptions) { var babelEnv = getBabelEnv.call(this); var babelEnvConfig = babelOptions.env || {}; var pluginsPromises = [ doProcessPlugins.call(this, babel, babelOptions.plugins) ]; for (var envName in babelEnvConfig) { // do not process plugins if the current environment does not match // the environment in which the plugins are set to be used if (babelEnv === envName) { var plugins = babelEnvConfig[envName].plugins || []; pluginsPromises.push(doProcessPlugins.call(this, babel, plugins)); } } return Promise.all(pluginsPromises) .then(function(results) { var plugins = []; // results is an array of arrays, flatten it out! results.forEach(function(processedPlugins) { plugins = plugins.concat(processedPlugins); }); return plugins; }); } /** * Collects builtin plugin names and non builtins functions * * @param {Object} babel The babel object exported by babel-standalone * @param {BabelPlugin[]} babelPlugins A list of babel plugins * @return {Promise.<BabelPlugin[]>} A promise that resolves to a list * of babel-standalone builtin plugin names and non-builtin plugin * functions */ function doProcessPlugins(babel, babelPlugins) { var promises = []; var plugins = babelPlugins || []; plugins.forEach(function(plugin) { var name = getPresetOrPluginName(plugin); if (!includesPresetOrPluginName(plugin) || isBuiltinPlugin(babel, name)) { promises.push(plugin); } else if (!isBuiltinPlugin(babel, name)) { var parent = this.configMain || "package.json!npm"; var npmPluginNameOrPath = getNpmPluginNameOrPath(name); // import the plugin! promises.push(this["import"](npmPluginNameOrPath, { name: parent }) .then(function(mod) { var exported = mod.__esModule ? mod["default"] : mod; if (typeof plugin === "string") { return exported; } // assume the array form was provided else { // [ pluginFunction, pluginOptions ] return [exported, plugin[1]]; } })); } }, this); return Promise.all(promises); } /** * Whether the plugin is built in babel-standalone * * @param {Object} babel The babel object exported by babel-standalone * @param {string} pluginName The plugin name to be checked * @return {boolean} */ function isBuiltinPlugin(babel, pluginName) { var isNpmPluginName = /^(?:babel-plugin-)/; var availablePlugins = babel.availablePlugins || {}; // babel-standalone registers its bundled plugins using the shorthand name var shorthand = isNpmPluginName.test(pluginName) ? pluginName.replace("babel-plugin-", "") : pluginName; return !!availablePlugins[shorthand]; } /** * Returns babel full plugin name if shorthand was used or the path provided * * @param {string} name The entry in the plugin array * @return {string} Relative/absolute path to plugin or babel npm plugin name * * If a babel plugin is on npm, it can be set in the `plugins` array using * one of the following forms: * * 1) full plugin name, e.g `"plugins": ["babel-plugin-myPlugin"]` * 2) relative/absolute path, e.g: `"plugins": ["./node_modules/asdf/plugin"]` * 3) using a shorthand, e.g: `"plugins": ["myPlugin"]` * * Since plugins are loaded through steal, we need to make sure the full * plugin name is passed to `steal.import` so the npm extension can locate * the babel plugin. Relative/absolute paths should be loaded as any other * module. */ function getNpmPluginNameOrPath(name) { var isPath = /\//; var isBabelPluginName = /^(?:babel-plugin-)/; return isPath.test(name) || isBabelPluginName.test(name) ? name : "babel-plugin-" + name; } }()); function getBabelPlugins(current) { var plugins = current || []; var required = "transform-es2015-modules-systemjs"; if (plugins.indexOf(required) === -1) { plugins.unshift(required); } return plugins; } var babelES2015Preset = "es2015-no-commonjs"; function getBabelPresets(current, loader) { var presets = current || []; var forceES5 = loader.forceES5 !== false; var defaultPresets = forceES5 ? [babelES2015Preset, "react", "stage-0"] : ["react"]; // if the user provided a list of presets to be used, treat the // BABEL_ES2015_PRESET as required if stealCondig.forceES5 is `true` if (presets.length) { if (forceES5) { if (presets.indexOf(babelES2015Preset) != -1) { presets.unshift(babelES2015Preset); } } } return presets.length ? presets : defaultPresets; } function getBabelOptionsFromLoad(load) { var pkg = load.metadata.npmPackage; if(pkg) { var steal = pkg.steal || pkg.system; if(steal && steal.babelOptions) { return steal.babelOptions; } } return this.babelOptions || {}; } /** * Returns the babel version * @param {Object} babel The babel object * @return {number} The babel version */ function getBabelVersion(babel) { var babelVersion = babel.version ? +babel.version.split(".")[0] : 6; return babelVersion || 6; } function getBabelOptions(load, babel) { var loader = this; var options = getBabelOptionsFromLoad.call(loader, load); options.sourceMap = "inline"; options.filename = load.address; options.code = true; options.ast = false; if (getBabelVersion(babel) >= 6) { // delete the old babel options if they are present in config delete options.optional; delete options.whitelist; delete options.blacklist; // make sure presents and plugins needed for Steal to work // correctly are set options.presets = getBabelPresets(options.presets, loader); options.plugins = getBabelPlugins(options.plugins); } else { options.modules = "system"; if (!options.blacklist) { options.blacklist = ["react"]; } } return options; } /**presets * A Babel preset as defined in `babelOptions.presets` * @typedef {string|Function|Object|<string, Object>[]|<Function, Object>[]|<Object, Object>} BabelPreset */ var processBabelPresets = (function() { /** * Returns a list of babel presets to be used during transpilation * * Collects the babel presets defined in `babelOptions.presets` plus * the environment dependant presets. * * @param {Object} babel The babel object exported by babel-standalone * @param {babelOptions} babelOptions The babel configuration object * @return {Promise.<BabelPreset[]>} Promise that resolves to a list of babel presets */ return function processBabelPresets(babel, babelOptions) { var babelEnv = getBabelEnv.call(this); var babelEnvConfig = babelOptions.env || {}; var presetsPromises = [ doProcessPresets.call(this, babel, babelOptions.presets) ]; for (var envName in babelEnvConfig) { // do not process presets if the current environment does not match // the environment in which the presets are set to be used if (babelEnv === envName) { var presets = babelEnvConfig[envName].presets || []; presetsPromises.push(doProcessPresets.call(this, babel, presets)); } } return Promise.all(presetsPromises) .then(function(results) { var presets = []; // results is an array of arrays, flatten it out! results.forEach(function(processedPresets) { presets = presets.concat(processedPresets); }); return presets; });