diff --git a/spec.html b/spec.html index 25cfea5..28fbff6 100644 --- a/spec.html +++ b/spec.html @@ -103,7 +103,7 @@

EvaluateImportCall ( _specifierExpression_ [ , _optionsExpression_ ] )

1. Append { [[Key]]: _key_, [[Value]]: _value_ } to _assertions_. 1. Sort _assertions_ by the code point order of the [[Key]] of each element. NOTE: This sorting is observable only in that hosts are prohibited from distinguishing among assertions by the order they occur in. 1. Let _moduleRequest_ be a new ModuleRequest Record { [[Specifier]]: _specifierString_, [[Assertions]]: _assertions_ }. - 1. Perform ! HostImportModuleDynamically(_referencingScriptOrModule_, _moduleRequest_, _promiseCapability_). + 1. Perform HostLoadImportedModule(_referrer_, _moduleRequest_, ~empty~, _promiseCapability_). 1. Return _promiseCapability_.[[Promise]]. @@ -120,39 +120,42 @@

EvaluateImportCall ( _specifierExpression_ [ , _optionsExpression_ ] )

- -

Runtime Semantics: HostResolveImportedModule ( _referencingScriptOrModule_, _specifier_ _moduleRequest_ )

-

HostResolveImportedModule is an implementation-defined abstract operation that provides the concrete Module Record subclass instance that corresponds to the |ModuleSpecifier| String, _specifier_,the ModuleRequest Record _moduleRequest_ occurring within the context of the script or module represented by the Script Record or Module Record _referencingScriptOrModule_. _referencingScriptOrModule_ may also be *null*, if the resolution is being performed in the context of an `import()` expression, and there is no active script or module at that time.

+ +

HostLoadImportedModule ( _referrer_, _specifier__moduleRequest_, _hostDefined_, _payload_ )

+

The host-defined abstract operation HostLoadImportedModule takes arguments _referrer_ (a Script Record, a Cyclic Module Record, or a Realm Record), _specifier_ (a String)_moduleRequest_ (a ModuleRequest Record), _hostDefined_ (anything), and _payload_ (a GraphLoadingState Record or a PromiseCapability Record) and returns ~unused~.

-

An example of when _referencingScriptOrModule_ can be *null* is in a web browser host. There, if a user clicks on a control given by

+

An example of when _referrer_ can be a Realm Record is in a web browser host. There, if a user clicks on a control given by

<button type="button" onclick="import('./foo.mjs')">Click me</button>

there will be no active script or module at the time the `import()` expression runs. More generally, this can happen in any situation where the host pushes execution contexts with *null* ScriptOrModule components onto the execution context stack.

-

The implementation of HostResolveImportedModule must conform to the following requirements:

+

An implementation of HostLoadImportedModule must conform to the following requirements:

-

Multiple different _referencingScriptOrModule_, _specifier_ _moduleRequest_.[[Specifier]] pairs may map to the same Module Record instance. The actual mapping semantic is implementation-defined but typically a normalization process is applied to _specifier_ as part of the mapping process. A typical normalization process would include actions such as alphabetic case folding and expansion of relative and abbreviated path specifiers.

+ +

The actual process performed is host-defined, but typically consists of performing whatever I/O operations are necessary to load the appropriate Module Record. Multiple different (_referrer_, _specifier__moduleRequest_.[[Specifier]]) pairs may map to the same Module Record instance. The actual mapping semantic is host-defined but typically a normalization process is applied to _specifier__moduleRequest_.[[Specifier]] as part of the mapping process. A typical normalization process would include actions such as expansion of relative and abbreviated path specifiers.

The above text implies that is recommended but not required that hosts do not use _moduleRequest_.[[Assertions]] as part of the module cache key. In either case, an exception thrown from an import with a given assertion list does not rule out success of another import with the same specifier but a different assertion list.

@@ -166,67 +169,41 @@

Runtime Semantics: HostResolveImportedModule ( _referencingScriptOrModule_, - -

Runtime Semantics: HostImportModuleDynamically ( _referencingScriptOrModule_, _specifier_, _moduleRequest_, _promiseCapability_ )

-

HostImportModuleDynamically is an implementation-defined abstract operation that performs any necessary setup work in order to make available the module corresponding to the |ModuleSpecifier| String, _specifier_,ModuleRequest Record _moduleRequest_ occurring within the context of the script or module represented by the Script Record or Module Record _referencingScriptOrModule_. (_referencingScriptOrModule_ may also be *null*, if there is no active script or module when the `import()` expression occurs.) It then performs FinishDynamicImport to finish the dynamic import process.

- - -

The implementation of HostImportModuleDynamically must conform to the following requirements:

- -
    -
  • - The abstract operation must always complete normally with *undefined*. Success or failure must instead be signaled as discussed below. -
  • -
  • - The host environment must conform to one of the two following sets of requirements: -
    -
    Success path
    - -
    -
      -
    • At some future time, the host environment must perform FinishDynamicImport(_referencingScriptOrModule_, _specifier_, _moduleRequest_, _promiseCapability_, NormalCompletion(*undefined*)).
    • - -
    • Any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments _referencingScriptOrModule_, and _specifier_ _moduleRequest_ must complete normally.
    • - -
    • The completion value of any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments _referencingScriptOrModule_, and _specifier_, _moduleRequest_ must be a module which has already been evaluated, i.e. whose Evaluate concrete method has already been called and returned a normal completion.
    • -
    -
    - -
    Failure path
    - -
    -
      -
    • At some future time, the host environment must perform FinishDynamicImport(_referencingScriptOrModule_, _specifier_, _moduleRequest_, _promiseCapability_, an abrupt completion), with the abrupt completion representing the cause of failure.
    • -
    -
    -
    -
  • -
  • - If the host environment takes the success path once for a given _referencingScriptOrModule_, _specifier_, _moduleRequest_ pair, it must always do so for subsequent calls. -
  • -
  • - The operation must not call _promiseCapability_.[[Resolve]] or _promiseCapability_.[[Reject]], but instead must treat _promiseCapability_ as an opaque identifying value to be passed through to FinishDynamicImport. -
  • -
- -

The actual process performed is implementation-defined, but typically consists of performing whatever I/O operations are necessary to allow HostResolveImportedModule to synchronously retrieve the appropriate Module Record, and then calling its Evaluate concrete method. This might require performing similar normalization as HostResolveImportedModule does.

-
- - -

Runtime Semantics: FinishDynamicImport ( _referencingScriptOrModule_, _specifier_, _moduleRequest_, _promiseCapability_, _completion_ )

-

The abstract operation FinishDynamicImport takes arguments _referencingScriptOrModule_, _specifier_, _moduleRequest_ (a ModuleRequest Record), _promiseCapability_, and _completion_. FinishDynamicImport completes the process of a dynamic import originally started by an `import()` call, resolving or rejecting the promise returned by that call as appropriate according to _completion_. It is performed by host environments as part of HostImportModuleDynamically. It performs the following steps when called:

- + +

FinishLoadingImportedModule ( _referrer_, _specifier__moduleRequest_, _payload_, _result_ )

+

The abstract operation FinishLoadingImportedModule takes arguments _referrer_ (a Script Record, a Cyclic Module Record, or a Realm Record), _specifier_ (a String)_moduleRequest_ (a ModuleRequest Record), _payload_ (a GraphLoadingState Record or a PromiseCapability Record), and _result_ (either a normal completion containing a Module Record or a throw completion) and returns ~unused~.

- 1. If _completion_ is an abrupt completion, then perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _completion_.[[Value]] »). + 1. If _result_ is a normal completion, then + 1. If _referrer_.[[LoadedModules]] contains a Record _record_ such that _record_.[[Specifier]] is _moduleRequest_.[[Specifier]] and AssertionsEqual(_record_.[[Assertions]], _moduleRequest_.[[Assertions]]) is *true*, then + 1. Assert: _record_.[[Module]] is _result_.[[Value]]. + 1. Else, add Record { [[Specifier]]: _moduleRequest_.[[Specifier]], [[Assertions]]: _moduleRequest_.[[Assertions]], [[Module]]: _result_.[[Value]] } to _referrer_.[[LoadedModules]]. + 1. If _payload_ is a GraphLoadingState Record, then + 1. Perform ContinueModuleLoading(_payload_, _result_). 1. Else, - 1. Assert: _completion_ is a normal completion and _completion_.[[Value]] is *undefined*. - 1. Let _moduleRecord_ be ! HostResolveImportedModule(_referencingScriptOrModule_, _specifier_, _moduleRequest_). - 1. Assert: Evaluate has already been invoked on _moduleRecord_ and successfully completed. - 1. Let _namespace_ be GetModuleNamespace(_moduleRecord_). - 1. If _namespace_ is an abrupt completion, perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _namespace_.[[Value]] »). - 1. Else, perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _namespace_.[[Value]] »). + 1. Perform ContinueDynamicImport(_payload_, _result_). + 1. Return ~unused~. + + +

The description of the [[LoadedModules]] field of Realm Record, Script Record, and Cyclic Module Record should be updated to include the [[Assertions]] field.

+
+ + +

AssertionsEqual(_left_, _right_)

+

The abstract operation AssertionsEqual takes arguments _left_ and _right_ (two Lists of Records { [[Key]]: a String, [[Value]]: a String }), and returns a Boolean.

+ + + 1. If the number of elements in _left_ is not the same as the number of elements in _right_, return *false*. + 1. For each Record { [[Key]], [[Value]] } _r_ of _left_, do + 1. Let _found_ be *false*. + 1. For each Record { [[Key]], [[Value]] } _s_ of _right_, do + 1. If _r_.[[Key]] is _s_.[[Key]] and _r_.[[Value]] is _s_.[[Value]], then + 1. Set _found_ to *true*. + 1. If _found_ is *false*, return *false*. + 1. Return *true*. + +
@@ -312,7 +289,7 @@

Static Semantics: StringValue

ModuleRequest Records

A ModuleRequest Record represents the request to import a module with given import assertions. It consists of the following fields:

- + @@ -558,7 +535,7 @@

Sample host integration: The Web embedding

  • The module script would have an additional item, which would be the module type, as a string (e.g., *"json"*), or *undefined* for a JavaScript module.
  • -
  • HostResolveImportedModule and HostImportModuleDynamically would take a ModuleRequest Record parameter in place of a specifier string, which would be passed down through several abstract operations to reach the fetch a single module script algorithm. Somewhere near the entrypoint, if the ModuleRequest Record's [[Assertions]] field has an element _entry_ such that _entry_.[[Key]] is *"type"*, then let _type_ be _entry_.[[Value]]; otherwise let _type_ be *undefined*. If the type is invalid, then an exception is thrown and module loading fails. Otherwise, this will equal the module type, if the module can be successfully fetched with a matching MIME type.
  • +
  • HostLoadImportedModule would take a ModuleRequest Record parameter in place of a specifier string, which would be passed down through several abstract operations to reach the fetch a single module script algorithm. Somewhere near the entrypoint, if the ModuleRequest Record's [[Assertions]] field has an element _entry_ such that _entry_.[[Key]] is *"type"*, then let _type_ be _entry_.[[Value]]; otherwise let _type_ be *undefined*. If the type is invalid, then an exception is thrown and module loading fails. Otherwise, this will equal the module type, if the module can be successfully fetched with a matching MIME type.
  • In the fetch the descendents of a module script algorithm, when iterating over [[RequestedModules]], the elements are ModuleRequest Records rather than just specifier strings; these Records is passed on to the internal module script graph fetching procedure (which sends it to "fetch a single module script". Other usage sites of [[RequestedModules]] ignore the assertion.
  • "Fetch a single module script" would check the assertion in two places: