Last active
May 1, 2016 02:08
-
-
Save rksm/e9ab242c5c4856d7550d14e1a781caf7 to your computer and use it in GitHub Desktop.
Exporting bundles in register format from loaded modules in SystemJS, see register format spec https://github.com/ModuleLoader/es6-module-loader/wiki/System.register-Explained
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global System, beforeEach, afterEach, describe, it*/ | |
import { expect } from "mocha-es6"; | |
import { removeDir, removeFile, createFiles, writeFile, modifyFile, readFile, inspect as i } from "./helpers.js"; | |
import { registerPackage } from "../src/packages.js"; | |
import { getSystem, removeSystem, printSystemConfig } from "../src/system.js"; | |
import { bundle } from "../src/bundling.js"; | |
var testDir = System.normalizeSync("lively.modules/tests/"); | |
describe("bundling", function() { | |
var System; | |
var files = { | |
"test-project": { | |
"file-1.js": "export var y = 1;", | |
"file-2.js": "import { y } from './file-1.js'; export var x = 1 + y;", | |
"file-3.js": "exports.x = 23;", | |
"file-4.js": "exports.y = require('./file-3.js').x;", | |
"file-5.js": "import { x } from './file-3.js'; export var y = 1 + x;", | |
} | |
} | |
beforeEach(() => { | |
System = getSystem("test", {baseURL: testDir}); | |
return createFiles(testDir, files); | |
}); | |
afterEach(() => { | |
removeSystem("test"); | |
return removeDir(testDir + "test-project"); | |
}); | |
describe("creation", () => { | |
it("can bundle es6 modules", () => | |
bundle(System, "test-project/test-bundle.js", ["test-project/file-1.js", "test-project/file-2.js"]) | |
.then(() => readFile(testDir + "test-project/test-bundle.js")) | |
.then(content => expect(content) | |
.to.match(new RegExp(`System.register\\('${testDir}test-project/file-1.js', \\[\\]`)) | |
.to.match(new RegExp(`System.register\\('${testDir}test-project/file-2.js', \\['./file-1.js'\\]`)))); | |
it("can bundle cjs files", () => | |
bundle(System, "test-project/test-bundle-2.js", ["test-project/file-3.js", "test-project/file-4.js"]) | |
.then(() => readFile(testDir + "test-project/test-bundle-2.js")) | |
.then(content => expect(content).to.match(new RegExp(`System.registerDynamic\\('${testDir}test-project/file-4.js', \\['./file-3.js'\\]`)))); | |
it("can bundle es6 + cjs files", () => | |
bundle(System, "test-project/test-bundle-3.js", ["test-project/file-5.js", "test-project/file-3.js"]) | |
.then(() => readFile(testDir + "test-project/test-bundle-3.js")) | |
.then(content => expect(content).to.match(new RegExp(`System.register\\('${testDir}test-project/file-5.js', \\['./file-3.js'\\]`)))); | |
}); | |
describe("loading", () => { | |
it("loads bundle as part of package", () => | |
bundle(System, "test-project/test-bundle-3.js", ["test-project/file-5.js", "test-project/file-3.js"]) | |
.then(() => modifyFile(testDir + "test-project/file-5.js", content => content.replace(/1 \+ x/, "2 + x"))) | |
.then(() => { removeSystem("test"); System = getSystem("test", {baseURL: testDir}); }) | |
.then(() => { | |
writeFile(testDir + "test-project/package.json", JSON.stringify({ | |
name: "test-project", | |
lively: {bundles: {"test-bundle-3.js": ["./file-5.js", "./file-3.js"]}} | |
}, null, 2)) | |
}) | |
.then(() => registerPackage(System, testDir + "test-project")) | |
.then(() => System.import("test-project/file-5.js")) | |
.then(m => expect(m.y).to.equal(24))); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Path, arr } from "lively.lang"; | |
import * as ast from "lively.ast"; | |
import { writeFile, removeFile } from "../tests/helpers.js"; | |
export { bundle } | |
function bundle(System, bundleFile, files) { | |
// files = [{moduleName, nameInBundle}] | |
return Promise.all(files.map(ea => { | |
var moduleName = typeof ea === "string" ? ea : ea.moduleName; | |
if (!moduleName) throw new Error("Error bundling module " + ea); | |
var newName = ea.nameInBundle || moduleName; | |
return System.normalize(moduleName) | |
.then(url => | |
(System.get(url) ? Promise.resolve() : System.import(url)) | |
.then(() => createRegisterModuleFor(System, url, ea.nameInBundle))); | |
})) | |
.then(sources => | |
System.normalize(bundleFile) | |
.then(outFile => writeFile(outFile, sources.join('\n')))); | |
} | |
function createRegisterModuleFor(System, url, nameInBundle, formatOverride) { | |
var load = System.loads && System.loads[url]; | |
if (!load) throw new Error(url + " not loaded / traced!"); | |
var format = formatOverride || load.metadata.format; | |
if (format === "json") { | |
return createJSONRegisterDynamicModuleFromLoad(System, url, nameInBundle, load); | |
} else if (format === "esm" || format === "es6") { | |
return createRegisterModuleFromLoad(load, nameInBundle); | |
} else if (format === "global") { | |
return createGlobalRegisterDynamicModule(System, url, nameInBundle, load.source, load.deps); | |
} else if (format === "cjs") { | |
return createCommonJSRegisterDynamicModule(System, url, nameInBundle, load.metadata.entry.executingRequire, load.deps); | |
} else { | |
throw new Error("Cannot create register module for " + url + " with format " + format); | |
} | |
} | |
function createRegisterModuleFromLoad(load, nameInBundle) { | |
return new Promise((resolve, reject) => { | |
var name = load.name; | |
if (!load.source) return reject(new Error("No source for " + name)); | |
var parsed = ast.parse(load.source); | |
if ("CallExpression" !== Path("body.0.expression.type").get(parsed)) | |
return reject(new Error("Load source is not a call Expression (" + name + ")")); | |
if ("CallExpression" !== Path("body.0.expression.callee.body.body.0.expression.type").get(parsed)) | |
return reject(new Error("Load source body inner is not a System.register call expressions (" + name + ")")); | |
if ("System" !== Path("body.0.expression.callee.body.body.0.expression.callee.object.name").get(parsed)) | |
return reject(new Error("Not a call to System! (" + name + ")")); | |
if ("register" !== Path("body.0.expression.callee.body.body.0.expression.callee.property.name").get(parsed)) | |
return reject(new Error("Not a call to System.register! (" + name + ")")); | |
var moduleName = nameInBundle || Path("body.0.expression.arguments.0.value").get(parsed); | |
if (!moduleName) | |
return reject(new Error("Could not extract module name from " + name)); | |
var registerCall = Path("body.0.expression.callee.body.body.0.expression").get(parsed) | |
registerCall["arguments"].unshift({type: "Literal", value: moduleName}) | |
resolve(ast.stringify(registerCall)); | |
}); | |
} | |
function createGlobalRegisterDynamicModule(System, url, nameInBundle, source, deps) { | |
var modSource = `var _retrieveGlobal = System.get("@@global-helpers").prepareGlobal(module.id, null, null);\n` | |
+ `(function() {\n${source}\n})();\n` | |
+ "return _retrieveGlobal();" | |
return createRegisterDynamicModuleWithSource(System, url, nameInBundle, modSource, false, deps); | |
} | |
function createCommonJSRegisterDynamicModule(System, url, nameInBundle, executingRequire, deps) { | |
// FIXME! deps... | |
var load = {status: 'loading', address: url, name: url, linkSets: [], dependencies: [], metadata: {}}; | |
return System.fetch(load).then(source => | |
createRegisterDynamicModuleWithSource(System, url, nameInBundle, source, executingRequire, deps)); | |
} | |
function createJSONRegisterDynamicModuleFromLoad(System, url, nameInBundle, load) { | |
return createRegisterDynamicModuleWithSource(System, url, nameInBundle, "return " + load.source, false, []); | |
} | |
function createRegisterDynamicModuleWithSource(System, url, nameInBundle, source, executingRequire, deps) { | |
var depsString = "[" + (deps.length ? "'" + deps.join("', '") + "'" : "") + "]"; | |
return Promise.resolve( | |
`System.registerDynamic('${nameInBundle || url}', ${depsString}, ${!!executingRequire}, ` | |
+ `function(require, exports, module) {\n${source}\n});\n`); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global System, beforeEach, afterEach, describe, it*/ | |
import { expect } from "mocha-es6"; | |
import { getSystem, removeSystem, moduleRecordFor, moduleEnv, sourceOf } from "../src/system.js"; | |
import { importSync } from "../src/sync-loader.js"; | |
function defineEntries(System, loadLog) { | |
// a -> b <-> c | |
System.register('a.js', ['./b.js'], function (_export) { | |
'use strict'; | |
loadLog.push("declared a"); | |
var b; | |
return { | |
setters: [_b => { loadLog.push("setters in a"); b = _b.default; }], | |
execute: function () { loadLog.push("body a"); _export('default', "exported from a, " + b); }}; | |
}) | |
System.register('b.js', ['./c.js'], function (_export) { | |
'use strict'; | |
loadLog.push("declared b"); | |
var c; | |
return { | |
setters: [_c => { loadLog.push("setters in b"); c = _c.default; }], | |
execute: function() { loadLog.push("body b"); _export('default', "exported from b, " + c); }}; | |
}) | |
System.register('c.js', ["./b.js"], function (_export) { | |
'use strict'; | |
loadLog.push("declared c"); | |
var b; | |
return { | |
setters: [_b => { loadLog.push("setters in c"); b = _b.default; }], | |
execute: function() { loadLog.push("body c"); _export('default', "exported from c"); }}; | |
}) | |
} | |
describe("sync loader", () => { | |
var S; | |
beforeEach(() => S = getSystem("lang-test")); | |
afterEach(() => removeSystem("lang-test")); | |
it("loads register-modules right away", () => { | |
var log = []; | |
defineEntries(S, log); | |
var exported = importSync(S, "a"); | |
expect(exported.default).to.equal("exported from a, exported from b, exported from c"); | |
expect(log.join(",")).to.equal('declared c,declared b,setters in b,setters in c,declared a,setters in a,body c,setters in b,body b,setters in c,setters in a,body a'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TODO | |
// [ ] originalIndices | |
// [ ] esm modules | |
// [ ] nodejs native modules | |
// [ ] how to get source, especially for trace? | |
var __global = System.get("@system-env").node ? | |
global : (typeof window !== "undefined" ? | |
window : (typeof self !== "undefined" ? self : this)) | |
import { graph, obj } from "lively.lang"; | |
import { applyConfig as realApplyConfig } from "./packages.js"; | |
import { getSystem, removeSystem } from "./system.js"; | |
export { importSync, getSystem, removeSystem } | |
function importSync(System, moduleName) { | |
var id = System.normalizeSync(moduleName); | |
// if it's a package.json, load + install it into System object and apply | |
// it's settings to the System config | |
var configMatch = id.match(/(.*)package\.json(\.js)?$/); | |
if (configMatch) { | |
var cfg = loadPackageConfigFromDefined(System, id), | |
pkgURL = configMatch[1].replace(/\/$/, ""); | |
applyConfig(System, cfg, pkgURL); | |
return cfg; | |
} | |
// Otherwise do a normal load of `moduleName`. Find and order the | |
// dependencies, then import (declare, link, instantiate, evaluate) the target | |
// module (which will load the dependencies in turn) | |
var baseURL = id.split("/").slice(0,-1).join("/"), | |
entries = getDefinedAsEntries(System, baseURL) | |
.map(entry => System.defined[entry.name] = entry); | |
if (!entries.length) { | |
throw new Error("Cannot find any registered modules for " + moduleName); | |
} | |
var missing = entriesWithMissingDeps(System, entries); | |
if (missing.length) | |
throw new Error(`Missing dependencies when loading ${baseURL}! ${JSON.stringify(missing, null, 2)}`) | |
var firstModule = entries.find(entry => entry.name === id) || entries[0], | |
sorted = sortedByDeps(System, entries, firstModule); | |
evaluateEntries(sorted, System); | |
return System.get(firstModule.name); | |
} | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
// package.json / configuration related | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
function loadPackageConfigFromDefined(System, packageConfigName) { | |
var configEntry = System.defined[packageConfigName]; | |
if (!configEntry) { | |
configEntry = System.defined[packageConfigName + ".js"]; | |
} | |
if (configEntry) { | |
var config = System.newModule(configEntry.execute()); | |
System.set(packageConfigName, config); | |
} | |
return config; | |
} | |
function applyConfig(System, config, pkgURL) { | |
if (config.systemjs) { | |
System.packages[pkgURL] = obj.deepMerge(System.packages[pkgURL], config.systemjs); | |
} | |
realApplyConfig(System, config, pkgURL); | |
} | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
// process System.defined entries | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
function getDefinedAsEntries(System, pkgURL) { | |
return Object.keys(System.defined).map(name => { | |
if (name.indexOf(pkgURL) !== 0) return null; | |
if (name.match(/\.json(\.js)?$/)) return null; | |
var def = System.defined[name]; | |
if (!def) return null; // alread loaded | |
var normalizedDeps = def.deps.map(dep => | |
System.normalizeSync(dep, def.name)) | |
var e = obj.deepMerge({deps: [], normalizedDeps: normalizedDeps, metadata: {}}, def); | |
e.esmExports = true; // ???? | |
return e; | |
}).filter(ea => !!ea); | |
} | |
function entriesWithMissingDeps(System, entries) { | |
// returns [{name, dep}] | |
var entryNames = entries.pluck("name"); | |
return entries.reduce((missing, ea) => { | |
var unresolved = ea.normalizedDeps.filter(dep => | |
dep[0] !== "@" // not a "special" dep | |
&& entryNames.indexOf(dep) === -1 // not defined | |
&& !System.get(dep) // not loaded | |
&& !Object.keys(System.defined || {}).some(unloaded => unloaded === dep) | |
); | |
return missing.concat(unresolved.map(dep => ({name: ea.name, dep: dep}))); | |
}, []); | |
} | |
function sortedByDeps(System, entries, mainEntry) { | |
if (!entries.length) return []; | |
var depGraph = entries.reduce((depGraph, ea) => { | |
depGraph[ea.name] = ea.normalizedDeps; return depGraph }, {}), | |
sorted = graph.sortByReference(depGraph, mainEntry.name).flatten(), | |
found = sorted.map(name => entries.find(e => e.name === name)).compact(), | |
notFound = entries.withoutAll(found); | |
if (notFound.length) | |
found = found.concat(sortedByDeps(notFound, notFound[0], System)); | |
return found; | |
} | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
// module loading / instantiation logic. Derived and compatible to systemjs 0.19.24 | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
function getModule(name, loader) { | |
// from SystemJS | |
// An analog to loader.get covering execution of all three layers (real declarative, simulated declarative, simulated dynamic) | |
var exports, entry = loader.defined[name]; | |
if (!entry) { | |
exports = loader.get(name); | |
if (!exports) | |
throw new Error('Unable to load dependency ' + name + '.'); | |
} | |
else { | |
if (entry.declarative) { | |
if (!entry.module) linkDeclarativeModule(entry, loader) | |
ensureEvaluated(name, [], loader); | |
} | |
else if (!entry.evaluated) | |
linkDynamicModule(entry, loader); | |
exports = entry.declarative && entry.esModule ? entry.esModule : entry.module.exports; | |
} | |
if ((!entry || entry.declarative) && exports && exports.__useDefault) | |
return exports['default']; | |
return exports; | |
} | |
function getESModule(exports) { | |
var esModule = {}; | |
// don't trigger getters/setters in environments that support them | |
if (typeof exports == 'object' || typeof exports == 'function') { | |
if (Object.getOwnPropertyDescriptor) { | |
var d; | |
for (var p in exports) | |
if (d = Object.getOwnPropertyDescriptor(exports, p)) | |
Object.defineProperty(esModule, p, d); | |
} | |
else { | |
var hasOwnProperty = exports && exports.hasOwnProperty; | |
for (var p in exports) { | |
if (!hasOwnProperty || exports.hasOwnProperty(p)) | |
esModule[p] = exports[p]; | |
} | |
} | |
} | |
esModule['default'] = exports; | |
Object.defineProperty(esModule, '__useDefault', { | |
value: true | |
}); | |
return esModule; | |
} | |
function linkDynamicModule(entry, loader) { | |
// from systemjs | |
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); | |
} | |
// try and normalize the dependency to see if we have another form | |
var nameNormalized = loader.normalizeSync(name, entry.name); | |
if (entry.normalizedDeps.indexOf(nameNormalized) != -1) | |
return getModule(nameNormalized, loader); | |
throw new Error('Module ' + name + ' not declared as a dependency of ' + entry.name); | |
}, exports, module); | |
if (output) | |
module.exports = output; | |
// create the esModule object, which allows ES6 named imports of dynamics | |
exports = module.exports; | |
// __esModule flag treats as already-named | |
var Module = System.get("@system-env").constructor; | |
if (exports && (exports.__esModule || exports instanceof Module)) | |
entry.esModule = exports; | |
// set module as 'default' export, then fake named exports by iterating properties | |
else if (entry.esmExports && exports !== __global) | |
entry.esModule = getESModule(exports); | |
// just use the 'default' export | |
else | |
entry.esModule = { 'default': exports }; | |
} | |
function getOrCreateModuleRecord(name, moduleRecords) { | |
return moduleRecords[name] || (moduleRecords[name] = { | |
name: name, | |
dependencies: [], | |
exports: {toString: () => "Module"}, | |
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 = importerModule.dependencies.indexOf(module); | |
importerModule.setters[importerIndex](exports); | |
} | |
} | |
module.locked = false; | |
return value; | |
}, { id: entry.name }); | |
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 setters for all entries with the matching dependency name | |
module.setters[i](depExports); | |
// TODO! | |
// originalIndices are currently not set when creating entry / load! | |
// var depsForSetters = entry.normalizedDeps.map(dep => depExports); | |
// getModule | |
// if (depsForSetters.include(undefined)) debugger; | |
// depsForSetters.forEach((depExports, i) => module.setters[i](depExports)); | |
// var originalIndices = entry.originalIndices[i]; | |
// for (var j = 0, len = originalIndices.length; j < len; ++j) { | |
// var index = originalIndices[j]; | |
// if (module.setters[index]) { | |
// module.setters[index](depExports); | |
// } | |
// } | |
} | |
} | |
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 (seen.indexOf(depName) == -1) { | |
if (!loader.defined[depName]) | |
loader.get(depName); | |
else | |
ensureEvaluated(depName, seen, loader); | |
} | |
} | |
if (entry.evaluated) | |
return; | |
entry.evaluated = true; | |
// return evaluateEntries([entry], loader)[0]; | |
if (!entry.module) show(entry.name) | |
entry.module.execute.call(__global); | |
} | |
function recordTrace(entry, System) { | |
if (!System.trace) return; | |
if (!System.loads) System.loads = {}; | |
var depMap = entry.deps.reduce((depMap, dep, i) => { | |
depMap[dep] = entry.normalizedDeps[i]; | |
return depMap; | |
}, {}); | |
System.loads[entry.name] = { | |
name: entry.name, | |
deps: entry.deps.concat([]), | |
depMap: depMap, | |
address: entry.address || entry.name, | |
metadata: entry.metadata, | |
source: entry.source, | |
kind: entry.declarative ? 'declarative' : 'dynamic' | |
}; | |
} | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
// Better support for sync. normalize | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
function doMapWithObject(mappedObject, pkg, loader) { | |
// SystemJS allows stuff like {events: {"node": "@node/events", "~node": "@empty"}} | |
// for conditional name lookups based on the environment. The resolution | |
// process in SystemJS is asynchronous, this one here synch. to support | |
// normalizeSync and a one-step-load | |
var env = loader.get(pkg.map['@env'] || '@system-env'); | |
// first map condition to match is used | |
var resolved; | |
for (var e in mappedObject) { | |
var negate = e[0] == '~'; | |
var value = readMemberExpression(negate ? e.substr(1) : e, env); | |
if (!negate && value || negate && !value) { | |
resolved = mappedObject[e]; | |
break; | |
} | |
} | |
if (resolved) { | |
if (typeof resolved != 'string') | |
throw new Error('Unable to map a package conditional to a package conditional.'); | |
} | |
return resolved; | |
} | |
function readMemberExpression(p, value) { | |
var pParts = p.split('.'); | |
while (pParts.length) | |
value = value[pParts.shift()]; | |
return value; | |
} | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
// sync. loading support | |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | |
function instantiateRegisteredEntry(entry, System) { | |
// instantiate : ({ name: NormalizedModuleName?, | |
// address: ModuleAddress?, | |
// source: ModuleSource, | |
// metadata: object }) | |
// -> Promise<ModuleFactory?> | |
return { | |
deps: entry.deps, | |
execute: function() { | |
System.defined[entry.name] = undefined; | |
if (entry.declarative && entry.module.execute) entry.module.execute(); | |
var module = System.newModule(entry.declarative ? entry.module.exports : entry.esModule); | |
System.set(entry.name, module); | |
recordTrace(entry, System); | |
return module; | |
} | |
} | |
} | |
function evaluateEntries(entries, System) { | |
// do link | |
// entries.map(entry => { | |
// if (entry.declarative) | |
// linkDeclarativeModule(entry, S) | |
// else { | |
// linkDynamicModule(entry, S) | |
// instantiateRegisteredEntry(entry, S).execute(); | |
// } | |
// }); | |
// return entries.map(entry => { | |
// if (entry.declarative) | |
// return instantiateRegisteredEntry(entry, S).execute(); | |
// return System.get(entry.name); | |
// }) | |
// do link | |
entries.forEach(entry => | |
entry.declarative ? | |
linkDeclarativeModule(entry, System) : | |
linkDynamicModule(entry, System)); | |
// ...and instantiate + execute | |
// execute will install loaded module in _loader.modules | |
return entries.map(entry => | |
instantiateRegisteredEntry(entry, System).execute()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment