diff --git a/README.md b/README.md
index ce17af9c..34fa3abe 100644
--- a/README.md
+++ b/README.md
@@ -20,8 +20,8 @@ SystemJS 2.0 provides two hookable base builds:
* Loads [System.register](docs/system-register.md) modules [supporting all ES module semantics](docs/system-register.md#semantics)
* Loads and resolves URLs only, excluding support for [bare specifier names](docs/package-name-maps.md#bare-specifiers) (eg `/lodash.js` but not `lodash`)
* Hookable loader supporting [custom extensions](docs/hooks.md)
- * Works in IE11+ when Promises are polyfilled
- * Ideal for use in [Rollup code-splitting builds](TODO)
+ * Works in IE11+ when [Promises are polyfilled](dist/ie11-polyfills.js)
+ * Ideal for use in [Rollup code-splitting builds](https://rollupjs.org/guide/en#experimental-code-splitting)
2. The 2.5KB [system.js](dist/system.min.js) loader:
@@ -33,9 +33,9 @@ SystemJS 2.0 provides two hookable base builds:
In addition, the following [pluggable extras](dist/extras) are provided:
-* AMD loading support (through `Window.define`)
-* Named exports convenience extension support for global and AMD module formats (`import { x } from './global.js'` instead of `import G from './global.js'; G.x`)
-* Translate loader support, using fetch and eval, supporting a hookable `loader.translate`
+* [AMD loading](dist/extras/amd.js) support (through `Window.define` which is created)
+* [Named exports](dist/extras/named-exports.js) convenience extension support for global and AMD module formats (`import { x } from './global.js'` instead of `import G from './global.js'; G.x`)
+* [Transform loader](dist/extras/transform.js) support, using fetch and eval, supporting a hookable `loader.transform`
Since all loader features are hookable, custom extensions can be easily made following the same approach as the bundled extras. See the [hooks documentation](docs/hooks.md) for more information.
@@ -44,8 +44,6 @@ For discussion, join the [Gitter Room](https://gitter.im/systemjs/systemjs).
Documentation
---
-* [Getting Started](docs/getting-started.md)
-* [Workflows](docs/workflows.md)
* [Package Name Maps](docs/package-name-maps.md)
* [API](docs/api.md)
* [System.register](docs/system-register.md)
@@ -74,7 +72,7 @@ Say `main.js` depends on loading `'lodash'`, then we can define a package name m
@@ -90,31 +88,23 @@ Say `main.js` depends on loading `'lodash'`, then we can define a package name m
### Browser transpilation
-Browser transpilation workflows are no longer first-class in SystemJS, and require a little more customization to work:
+To load ES modules directly in older browsers with SystemJS we can install and use the Babel plugin:
```html
-
+
+
-
```
-An extension for in-browser Babel compilation can be created easily this way, but SystemJS does not provide the
-individual translator implementations, as this is left for third-party implementors.
-
-### Third-party extensions
+### Loader Extensions
This list can be extended to include third-party loader extensions. Feel free to [post a PR to share your work](TODO).
-* Nothing yet :)
+* [plugin-babel](https://github.com/systemjs/plugin-babel) Supports ES module transformation into System.register with Babel.
### Contributing to SystemJS
diff --git a/docs/getting-started.md b/docs/getting-started.md
deleted file mode 100644
index bed40126..00000000
--- a/docs/getting-started.md
+++ /dev/null
@@ -1,172 +0,0 @@
-### Loading Modules
-
-Any URL can be loaded as a module with standard URL syntax:
-
-```html
-
-
-```
-
-Any type of module format can be loaded and it will be detected automatically by SystemJS.
-
-##### File access from files
-
-> _Note that when running locally, ensure you are running from a local server or a browser with local XHR requests enabled. If not you will get an error message._
-
-> _For Chrome on Mac, you can run it with: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files &> /dev/null &`_
-
-> _In Firefox this requires navigating to `about:config`, entering `security.fileuri.strict_origin_policy` in the filter box and toggling the option to false._
-
-### Loading ES6
-
-app/es6-file.js:
-```javascript
- export class q {
- constructor() {
- this.es6 = 'yay';
- }
- }
-```
-
-```html
-
-```
-
-ES6 modules define named exports, provided as getters on a special immutable `Module` object.
-
-* To build for production, see the [production workflows](production-workflows.md).
-* [Read more about SystemJS module format support](module-formats.md).
-
-### Loader Configuration
-
-Some of the standard configuration options and their use cases are described below.
-
-For a reference see the [Config API](config-api.md) page.
-
-#### baseURL
-
-The *baseURL* provides a mechanism for loading modules relative to a standard reference URL.
-
-This can be useful for being able to refer to the same module from many different page URLs or environments:
-
-```javascript
-SystemJS.config({
- baseURL: '/modules'
-});
-
-
-// loads /modules/jquery.js
-SystemJS.import('jquery.js');
-```
-
-Module names of the above form are referred to as _plain names_ and are always loaded baseURL-relative instead of
-parentURL relative like one would expect with ordinary URLs.
-
-When loading with relative syntax, modules are loaded not relative to the baseURL, but to the baseURI:
-
-```javascript
-// will load relative to the baseURI, regardless of baseURL
-SystemJS.import('./x.js');
-```
-
-> Note we always run the `SystemJS.config` function instead of setting instance properties directly as this will set the correct normalized baseURL in the process.
-
-#### Map Config
-
-The baseURL is very useful for providing an absolute reference URL for loading all modules, but we don't necessarily want to
-have to locate every single shared dependency from within one folder.
-
-Sometimes we want to load things from different places.
-
-Map configuration is useful here to be able to specify exactly where to locate a given package:
-
-```javascript
-SystemJS.config({
- map: {
- jquery: 'https://code.jquery.com/jquery.js'
- }
-});
-```
-
-Map configuration can also be used to map subpaths:
-
-```javascript
-SystemJS.config({
- map: {
- app: '/app/'
- }
-});
-
-// will load /app/main.js
-SystemJS.import('app/main.js');
-```
-
-Map configuration is always applied before the baseURL rule in the loader.
-
-### Plugin Loaders
-
-Plugins handle alternative loading scenarios, including loading assets such as CSS or images, and providing custom transpilation scenarios.
-
-Plugins can also inline into bundles or remain separate requests when using [SystemJS Builder](https://github.com/systemjs/builder).
-
-To create a custom plugin, see the documentation on [creating plugins](creating-plugins.md).
-
-#### Basic Use
-
-> Note that if using the `defaultJSExtensions` compatibility feature, plugins for resources with custom extensions will only work by using the [package configuration](config-api.md#packages) `defaultExtension: false` option to override this for specific packages.
-
-To use a plugin, set up the plugin itself as a standard module, either locating it in the baseURL or providing map configuration for it.
-
-In this case, we're using the [text plugin](https://github.com/systemjs/plugin-text) as an example.
-
-Then configure a custom resource to be loaded via the plugin, we then use meta configuration:
-
-```javascript
-SystemJS.config({
- // locate the plugin via map configuration
- // (alternatively have it in the baseURL)
- map: {
- text: '/path/to/text-plugin.js'
- },
- // use meta configuration to reference which modules
- // should use the plugin loader
- meta: {
- 'templates/*.html': {
- loader: 'text'
- }
- }
-});
-```
-
-Now any code that loads from `[baseURL]/templates/*.html` will use the text loader plugin and return the loaded content:
-
-app.js
-```javascript
-import htmlSource from 'templates/tpl.html';
-
-document.querySelector('.container').innerHTML = htmlSource;
-```
-
-When we build app.js, the text plugin will then automatically inline the templates into the bundle during the build.
-
-#### Plugin Syntax
-
-It is also possible to use syntax to load via plugins instead of configuration:
-
-```javascript
-SystemJS.import('some/file.txt!text')
-```
-
-When no plugin is explicitly specified the extension is used as the plugin name itself.
-
-> To use the Webpack-style plugin syntax `System.import('text!some/file.txt')` this can be enabled globally via `System.config({ pluginFirst: true })`.
diff --git a/docs/hooks.md b/docs/hooks.md
index f8013a32..c434166f 100644
--- a/docs/hooks.md
+++ b/docs/hooks.md
@@ -1,38 +1,75 @@
## Loader Hooks
+### Hooking the Loader
+
+The loader is designed to be hookable in a very light-weight way using only function extensions.
+
+The standard pattern for this is:
+
+```js
+const existingHook = System.constructor.prototype.hookName;
+System.constructor.prototype.hookName = function (args) {
+ return Promise.resolve(existingHook.call(this, args))
+ .then(function (existingHookResult) {
+ // custom hook here
+ return ...;
+ });
+};
+```
+
+When hooking the loader it is important to pay attention to the order in which hooks will apply, and to
+keep existing hooks running where they provide necessary functionality.
+
+In addition, some hooks are Promise-based, so Promise chaining
+also needs to be carefully applied only where necessary.
+
### Core Hooks
-#### createContext
+#### createContext(url) -> Object
-#### getRegister
+Used to populate the `import.meta` for a module, available at `_context.meta` in the [System.register module format](system-register.md).
-#### onload
+The default implementation is:
+
+```js
+System.constructor.prototype.createContext = function (url) {
+ return {
+ url
+ };
+};
+```
+
+#### getRegister() -> [deps: String[], declare: Function]
+
+> This hook is intended for custom module format integrations only.
+
+This function stores the last call to `System.register`, and is the companion hook for that function.
+
+It is important that this function is synchronous, as any event loop delay would result in uncertainty over which source evaluation
+resulted in this registration call.
+
+Custom module format support like AMD support is added by hooking the AMD registration in hook.
+
+#### resolve(id, parentUrl) -> Promise
+
+In the minimal s.js implementation, resolve is implemented as a synchronous function, so Promise.resolve should be used when extending this loader.
+
+Resolve should return a fully-valid URL for specification compatibility, but this is not enforced.
+
+#### onload(url, error) (sync)
+
+_This hook is not available in the s.js minimal loader build._
+
+For tracing functionality this is called on completion or failure of each and every module loaded into the registry.
+
+Such tracing can be used for analysis and to clear the loader registry using the `System.delete(url)` API to enable reloading and hot reloading workflows.
### Extras Hooks
-#### translate
+#### transform(url, source) -> Promise
-### Extending the Loader
+This hook is provided by the [transform extra](../dist/extras/transform.js).
-Extensions to the loader are made by amending its prototype (`System.constructor.prototype`).
+The default implementation is a pass-through transform that returns the fetched source.
-In addition to the hooks listed here, it is also possible to extend any of the [API methods of the loader](api.md) with these hooking patterns as well.
-
-The base loader provides the initial core hooks, while extensions can also define their own hooks in the same way to provide an extensible hookable loader.
-
-Hooks can be added via a duck-typing pattern:
-
-```js
-const systemJSPrototype = System.constructor.prototype;
-const import = systemJSPrototype.import ;
-systemJSPrototype.import = function (id, parentURL) {
- return Promise.resolve(import.call(this, id, parentURL))
- .then(function (module) {
- return module;
- });
-}
-```
-
-where hook code could come before or after previous code, but care should be taken to ensure that the previous hook continues to run under its same original assumptions and constraints.
-
-Note that some hooks are sync, so should not use promise resolution.
\ No newline at end of file
+For an example of a transform see the [Babel plugin transform](https://github.com/systemjs/plugin-babel).
\ No newline at end of file
diff --git a/docs/package-name-maps.md b/docs/package-name-maps.md
index 30404ce4..5dfa57b5 100644
--- a/docs/package-name-maps.md
+++ b/docs/package-name-maps.md
@@ -1 +1,136 @@
-TODO
\ No newline at end of file
+## Package Name Maps
+
+Package name maps are the [current specification](https://github.com/domenic/package-name-maps) for mapping bare specifier names in the browser.
+
+These are module specifiers like `"lodash"` which are not absolute URLs and do not start with `./`, `../` or `/`.
+
+> Note the package name maps specification is still under active development and as such this implementation will be subject to change.
+
+### Loading Package Name Maps
+
+Package name maps can be loaded inline or from a separate URL using a `
+```
+
+It is important that the package map is included before SystemJS itself for it to be picked up properly.
+
+### Packages
+
+For base-level specifier mappings, we can use the `"packages"` property:
+
+```html
+
+```
+
+The above will resolve any `import 'lodash'` call to the path we have provided.
+
+For submodules, loading `import 'lodash/x'` will resolve to `/path/to/x.js`.
+
+To more clearly define package folders we can use the expanded form of the packages configuration:
+
+```html
+
+```
+
+In this scenario `import 'lodash'` will resolve to `/path/to/lodash/index.js` while `import 'lodash/x'` will
+resolve to `/path/to/lodash/x`.
+
+### Scopes
+
+Package name maps also provide support for scoped mappings, where the mapping should only be applied within
+a specific base path.
+
+For example, say that we want `lodash` to resolve to one version in `/app` and that `/lib/x` should resolve
+a different version of lodash.
+
+This can be achieved with scoped packages:
+
+```html
+
+```
+
+Scopes still fallback to applying the global packages, so we only need to do this for packages that are different
+from their global resolutions.
+
+### Path Prefix
+
+For all mappings, we can define a base-level path prefix relative to which mappings apply:
+
+```html
+
+```
+
+Note that paths are loaded relative to their package names in certain cases, so this isn't always straightforward to
+follow. Absolute URLs can often be safer.
+
+### Excluded Features
+
+The SystemJS implementation of package maps excludes a couple of features from the spec:
+
+#### Nested Scopes
+
+Nested scopes is the ability to define a `"scopes"` within a scope, which is not currently supported.
+
+#### Scope Prefixes
+
+The spec supports `path_prefix` defined within scopes for custom base-level resolution within any given scope.
+
+Support for this feature is not included in this implementation.
+
+#### Spec and Implemnetation Feedback
+
+Part of the benefit of giving users a working version of an early spec is being able to get real user feedback on
+the spec.
+
+If you have suggestions, or notice cases where this implementation seems not
+to be following the spec properly feel free to post an issue.
diff --git a/docs/system-register.md b/docs/system-register.md
index 30404ce4..e81b44ed 100644
--- a/docs/system-register.md
+++ b/docs/system-register.md
@@ -1 +1,184 @@
-TODO
\ No newline at end of file
+## System.register
+
+### What it is
+
+System.register can be considered as a new module format designed to support the exact semantics of ES6 modules within ES5.
+
+This format provides support for:
+
+* Live bindings updates, including through reexports, star exports and namespace imports, and any combination of these
+* `import.meta`, including `import.meta.url`
+* Dynamic `import()`
+* Top-level await
+* Circular references including function hoisting (where functions in non-executed modules can be used in circular reference cases)
+
+By ensuring we cover all of these semantics, the guarantee is that if code works in browsers in ES modules, the associated
+System.register code can work with s.js providing a legacy fallback workflow that doesn't randomly break at semantic edge cases.
+
+This format was originally developed out of collaboration in Traceur, and is supported as an output in Babel, TypeScript and Rollup.
+
+### Format Definition
+
+The module wrapper takes the following structure:
+
+```js
+System.register([...deps...], function (_export, _context) {
+ return {
+ setters: [...setters...],
+ execute: function () {
+
+ }
+ };
+});
+```
+
+where:
+
+* `deps: String[]` - The array of module dependency strings, unresolved.
+* `setters: Function[]` - The array of functions to be called whenever one of the bindings of a dependency is updated. It is indexed in the same order as `deps`. Setter functions can be undefined for dependencies that have no exports.
+* `execute: Function` - This is called at the exact point of code execution, while the outer wrapper is called early, allowing the wrapper to export function declarations before execution.
+* `execute: AsyncFunction` - If using an asynchronous function for execute, top-level await execution support semantics are provided following [variant B of the specification](https://github.com/tc39/proposal-top-level-await#variant-b-top-level-await-does-not-block-sibling-execution).
+* `_export: (name: String, value: any) => value` - The direct form of the export function can be used to export bindings - `_export('exportName', value)`. It returns the set value for ease of use in expressions.
+* `_export: ({ [name: String]: any }) => value` - The bulk form of the export function allows setting an object of exports. This is not just sugar, but improves performance by calling fewer setter functions when used, so should be used whenever possible by implementations over the direct export form.
+* `_context.meta: Object` - This is an object representing the value of `import.meta` for a module execution. By default it will have `import.meta.url` present in SystemJS.
+* `_context.import: (id: String) => Promise` This is the contextual dynamic import function available to the module as the replacement for `import()`.
+
+> Note as of SystemJS 2.0 support for named `System.register(name, deps, declare)` is no longer supported, as instead code optimization approaches that combine modules
+ like with [Rollup's code-splitting workflows](https://rollupjs.org/guide/en#experimental-code-splitting) are recommended insteead.
+
+#### Why the System.register name
+
+Since `System` is the loader name, `System.register` is a function that allows us to _define_ a module directly into the loader instance. When code is executed, we only need to assume that `System` is in the scope of execution.
+
+The advantage is the same as the AMD `define` in that it can support browsers with CSP policies that do not support custom JS evaluation, only script tags from authorized hosts.
+
+### Semantic Cases
+
+For an example of how this format can be used to deal with semantics, consider the following ES module code and its associated transform:
+
+```js
+import { p as q } from './dep';
+
+var s = 'local';
+
+export function func() {
+ return q;
+}
+
+export class C {
+}
+```
+
+->
+
+```js
+System.register(['./dep'], function($__export, $__moduleContext) {
+ var s, C, q;
+ function func() {
+ return q;
+ }
+ $__export('func', func);
+ return {
+ setters: [
+ // every time a dependency updates an export,
+ // this function is called to update the local binding
+ // the setter array matches up with the dependency array above
+ function(m) {
+ q = m.p;
+ }
+ ],
+ execute: function() {
+ // use the export function to update the exports of this module
+ s = 'local';
+ $__export('C', C = $traceurRuntime.createClass(...));
+ }
+ };
+});
+```
+
+Initial exports and changes to exports are pushed through the setter function, `$__export`. Values of dependencies and
+changes to dependency bindings are set through the dependency setters, `setters`, corresponding to the `$__export` calls of dependencies.
+
+Functions and variables get hoisted into the declaration scope. This outer function sets up all the bindings,
+and the execution is entirely separated from this process. Hoisted functions are immediately exported.
+All of the modules in the tree first run this first function setting up all the bindings.
+Then we separately run all the execution functions left to right from the bottom of the tree ending at circular references.
+
+In this way we get the live binding and circular reference support exactly as expected by the spec,
+while supporting ES3 environments for the module syntax conversion.
+
+#### Deferred Execution
+
+The use of `return { setters: ..., execute: ... }` is done instead of direct execution to allow bindings to be fully propogated
+through the module tree before running execution functions. This separation of setting up bindings, and then running execution
+allows us to match the exact ES module execution semantics.
+
+This enables supporting the edge cases of for example:
+
+a.js
+```javascript
+import {b} from './b.js';
+export function a() {
+ b();
+}
+```
+
+b.js
+```javascript
+import {a} from './a.js';
+export function b() {
+ console.log('b');
+}
+a();
+```
+
+If a.js is imported first, then b.js will execute first. In ES module execution, b.js will successfully call the function export
+from a.js before a.js has even executed since function bindings are setup before execution. This is supported fully by
+the deferred loading step in this System.register approach.
+
+It can be argued that this full support of ES module circular references is unnecessary. There is minimal additional performance
+cost to this extra return statement though and it ensures that during the transition period where ES modules and traditional
+environments are running side-by-side, that the best parity is provided between the systems.
+
+#### Let and Uninitialized Bindings
+
+Due to the hoisting of variable declarations into the outer scope, it is assumed that `let` or `const` should be converted into `var` statements. While TDZ errors are not maintained (it is possible to set a variable before it is declared), the primary goal of the module format is that functional ES module code should be fully supported through System.register, and the converse that functional System.register code be functional ES module code is not a requirement of the format. As such, since functional ES module code should not have to rely on top-level TDZ errors for normal operation, this seems a suitable compromise for the format.
+
+Top-level bindings that are uninitialized should still be exported with undefined values to ensure they contribute the module shape.
+
+For example:
+
+```js
+export let x;
+export function p () {
+ x = 10;
+}
+```
+
+Could be written:
+
+```js
+ System.register([], function($__export, $__moduleContext) {
+ var x;
+ function p() {
+ x = 10;
+ }
+ $__export({
+ x: undefined,
+ p: p
+ });
+ return {
+ // setters: [], // (setters can be optional when empty)
+ execute: function() {
+ }
+ };
+ });
+```
+
+Although in the case of not having any dependencies, it could be equally valid to omit hoisting entirely.
+
+#### Top-level await
+
+Top-level await can be supported by returning a Promise from the `execute` function or making `execute` an asynchronous function.
+
+This can fully support synchronous subgraph execution remaining synchronous while also allowing the runtime to support the exact loading semantics desired. Currently SystemJS supports variant B of the spec.
\ No newline at end of file
diff --git a/docs/workflows.md b/docs/workflows.md
deleted file mode 100644
index 30404ce4..00000000
--- a/docs/workflows.md
+++ /dev/null
@@ -1 +0,0 @@
-TODO
\ No newline at end of file