Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module Blocks #7009

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 95 additions & 35 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -8328,6 +8328,16 @@ interface <dfn interface>DOMStringList</dfn> {
</ol>
</li>

<li>
<p>Otherwise, if <var>value</var> has [[ModuleBlockBody]] internal slot, then:</p>

<ol>
<li><p>Set <var>serialized</var> to { [[Type]]: "ModuleBlock",
[[ModuleBlockBody]]: <var>value</var>.[[ModuleBlockBody]],
[[HostDefined]]: <var>value</var>.[[HostDefined]] }.</p></li>
</ol>
</li>

<li>
<p>Otherwise, if <var>value</var> has an [[ErrorData]] internal slot and <var>value</var> is not
a <span>platform object</span>, then:</p>
Expand Down Expand Up @@ -8722,6 +8732,17 @@ o.myself = o;</code></pre>
</ol>
</li>

<li>
<p>Otherwise, if <var>serialized</var>.[[Type]] is "ModuleBlock", then:</p>

<ol>
<li><p>Set <var>value</var> to a new ModuleBlock object in <var>targetRealm</var>
whose [[ModuleBlockBody]] internal slot value is <var>value</var>.[[ModuleBlockBody]]
and whose [[HostDefined]] internal slot value is <var>value</var>.[[HostDefined]].</p></li>

</ol>
</li>

<li>
<p>Otherwise, if <var>serialized</var>.[[Type]] is "Array", then:</p>

Expand Down Expand Up @@ -90909,43 +90930,52 @@ document.querySelector("button").addEventListener("click", bound);
script</span> (on success).</p>

<ol>
<li><p>Let <var>url</var> be the result of <span data-x="resolve a module specifier">resolving a
<li><p>Let <var>specifier</var> be the result of <span data-x="resolve a module specifier">resolving a
module specifier</span> given <var>base URL</var> and <var>moduleRequest</var>.[[Specifier]].</p></li>

<li><p>If <var>url</var> is failure, then asynchronously complete this algorithm with null, and
return.</p></li>
<li>
<p>If <var>specifier</var> is a <span>module block</span>, then:</p>
<ol>
<li><p>Let <var>source text</var> be <var>specifier</var>.[[ModuleBlockBody]].</p></li>

<li><p>Assert: <var>moduleRequest</var>.[[Assertions]] does not contain any <span>Record</span>
<var>entry</var> such that <var>entry</var>.[[Key]] is not "<code data-x="">type</code>", because
we only asked for "<code data-x="">type</code>" assertions in
<span>HostGetSupportedImportAssertions</span>.</p></li>
<li><p>Let <var>module block base URL</var> be <var>specifier</var>.[[HostDefined]].</p></li>

<li><p>If <var>moduleRequest</var>.[[Assertions]] has a <span>Record</span> <var>entry</var>
such that <var>entry</var>.[[Key]] is "<code data-x="">type</code>", then let <var>module
type</var> be <var>entry</var>.[[Value]]. Otherwise let <var>module type</var> be "<code
data-x="">javascript</code>".</p></li>
<li><p>Let <var>result</var> be the result of <span>creating a module script</span> using
<var>source text</var>, <var>settings object</var>, <var>module block base URL</var>, and
<var>options</var>.</p></li>

<li><p>If <var>module type</var> is not "<code data-x="">javascript</code>", "<code
data-x="">css</code>", or "<code data-x="">json</code>", then asynchronously complete this
algorithm with null, and return.</p></li>
<li><p>Set <var>moduleMap</var>[<var>specifier</var>] to <var>module script</var>.</p></li>
</ol>
<p>else:</p>
<ol>
<li><p>Assert: <var>moduleRequest</var>.[[Assertions]] does not contain any <span>Record</span>
<var>entry</var> such that <var>entry</var>.[[Key]] is not "<code data-x="">type</code>", because
we only asked for "<code data-x="">type</code>" assertions in
<span>HostGetSupportedImportAssertions</span>.</p></li>

<li><p><span>Fetch a single module script</span> given <var>url</var>, <var>settings
object</var>, "<code data-x="">script</code>", <var>options</var>, <var>settings object</var>,
"<code data-x="">client</code>", <var>moduleRequest</var>, and with the
<var>top-level module fetch flag</var> set. If the caller of this algorithm specified custom
<span data-x="fetching-scripts-perform-fetch">perform the fetch</span> steps, pass those along as
well. Wait until the algorithm asynchronously completes with <var>result</var>.</p></li>
<li><p>If <var>moduleRequest</var>.[[Assertions]] has a <span>Record</span> <var>entry</var>
such that <var>entry</var>.[[Key]] is "<code data-x="">type</code>", then let <var>module
type</var> be <var>entry</var>.[[Value]]. Otherwise let <var>module type</var> be "<code
data-x="">javascript</code>".</p></li>

<li><p>If <var>result</var> is null, asynchronously complete this algorithm with null, and
return.</p></li>
<li><p>If <var>module type</var> is not "<code data-x="">javascript</code>", "<code
data-x="">css</code>", or "<code data-x="">json</code>", then asynchronously complete this
algorithm with null, and return.</p></li>

<li><p>Let <var>visited set</var> be « (<var>url</var>, <var>module type</var>) ».</p></li>
<li><p><span>Fetch a single module script</span> given <var>url</var>, <var>settings
object</var>, "<code data-x="">script</code>", <var>options</var>, <var>settings object</var>,
"<code data-x="">client</code>", <var>moduleRequest</var>, and with the
<var>top-level module fetch flag</var> set. If the caller of this algorithm specified custom
<span data-x="fetching-scripts-perform-fetch">perform the fetch</span> steps, pass those along as
well. Wait until the algorithm asynchronously completes with <var>result</var>.</p></li>
</ol>

<li><p><span data-x="fetch the descendants of and link a module script">Fetch the
descendants of and link</span> <var>result</var> given <var>settings object</var>,
<var>destination</var>, and <var>visited set</var>. When this asynchronously completes with
<var>final result</var>, asynchronously complete this algorithm with <var>final
result</var>.</p></li>
<li><p>Let <var>visited set</var> be « (<var>url</var>, <var>module type</var>) ».</p></li>
<li><p><span data-x="fetch the descendants of and link a module script">Fetch the
descendants of and link</span> <var>result</var> given <var>settings object</var>,
<var>destination</var>, and <var>visited set</var>. When this asynchronously completes with
<var>final result</var>, asynchronously complete this algorithm with <var>final
result</var>.</p></li>
</ol>

<p>To <dfn>fetch a modulepreload module script graph</dfn> given a <var>url</var>, a
Expand Down Expand Up @@ -92626,15 +92656,25 @@ dictionary <dfn dictionary>PromiseRejectionEventInit</dfn> : <span>EventInit</sp
</dl>

<p><span w-nodev>A <dfn>module map</dfn> is a <span data-x="ordered map">map</span> keyed by <span
data-x="tuple">tuples</span> consisting of a <span>URL record</span> and a <span>string</span>.
The <span>URL record</span> is the <span data-x="concept-request-url">request URL</span> at which
the module was fetched, and the <span>string</span> indicates the type of the module (e.g. "<code
data-x="">javascript</code>"). The <span>module map</span>'s values are either a <span>module
script</span>, null (used to represent failed fetches), or a placeholder value "<code
data-x="">fetching</code>". </span><span data-x="module map">Module maps</span> are used to ensure
that imported module scripts are only fetched, parsed, and evaluated once per
data-x="tuple">tuples</span>. The tuple consists of:</p>

<ol>
<li><p>A <span>URL record</span> or a <span>module block</span>.</p></li>
<li><p>A <span>string</span>.</p></li>
</ol>

<p>The <span>URL record</span> is the <span data-x="concept-request-url">request URL</span>
at which the module was fetched, and the <span>string</span> indicates the type of the module
(e.g. "<code data-x="">javascript</code>"). The <span>module map</span>'s values are either a
<span>module script</span>, null (used to represent failed fetches), or a placeholder value
"<code data-x="">fetching</code>". </span><span data-x="module map">Module maps</span> are used
to ensure that imported module scripts are only fetched, parsed, and evaluated once per
<code>Document</code> or <a href="#workers">worker</a>.</p>

<p>The module map is a weak map. The entries where tuple key has a module block are weakly held,
but tuple keys with the URL record keys are strongly held. This is because module block
instances may be collected throughout the lifetime of a realm.</p>

<div class="example">
<p>Since <span data-x="module map">module maps</span> are keyed by (URL, module type), the
following code will create three separate entries in the <span>module map</span>, since it
Expand Down Expand Up @@ -92951,6 +92991,26 @@ import "https://example.com/foo/../module2.mjs";</code></pre>
<li><p>Return <var>resolved module script</var>'s <span
data-x="concept-script-record">record</span>.</p></li>
</ol>
<h6><dfn>HostIntializeModuleBlock</dfn>(<var>moduleBlock</var>)</h6>

<p>JavaScript contains an <span>implementation-defined</span> <span
data-x="js-HostInitializeModuleBlock">HostIntializeModuleBlock</span> abstract operation. User
agents must use the following implementation: <ref spec=JAVASCRIPT></p>

<ol>
<li><p>Let <var>urlString</var> be null.</p></li>
<p>If <var>active script</var> is not null, then:</p>
<ol>
<li><p>If <var>active script</var>'s <var>base URL</var> is not null, then:</p></li>
<ol>
<li><p>Let <var>urlString</var> be <var>active script</var>'s <span
data-x="concept-script-base-url">base URL</span>, <span
data-x="concept-url-serializer">serialized</span>.</p></li>
</ol>
</ol>
</li>
<li><p>Set the <var>moduleBlock</var>.[[HostDefined]] to <var>urlString</var>.</p></li>
</ol>

<h6 id="hostgetsupportedimportassertions"><dfn>HostGetSupportedImportAssertions</dfn>()</h6>

Expand Down