Skip to content

Instantly share code, notes, and snippets.

@dherman
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dherman/8b138ebf3eb0f322644b to your computer and use it in GitHub Desktop.
Save dherman/8b138ebf3eb0f322644b to your computer and use it in GitHub Desktop.
combinatorics of top-level execution

Orthogonal Variables

Considering the full combinatorics of the space, there are four different independent variables for how to execute top-level code:

  • HTML vs JS: is the code loaded from an HTML tag or from a JS constructor?
  • script vs module: is the code executed as an ES(6) Script or Module?
  • worker vs sync: is the code loaded in a worker or synchronously?
  • URL vs source: is the code provided as a source string or a URL to an external file?

This leads to 2^4=16 combinations that have to be considered for the design. It doesn't mean authors actually have to deal with all this combinations, since (a) they don't all have to be supported, and (b) some can eventually become old-fashioned legacy.

There are also multiple kinds of workers (Worker, SharedWorker, ServiceWorker, possibly more in the future?).

Combinatorics

HTML, script, worker, URL

Suggested by Anne at https://www.w3.org/Bugs/Public/show_bug.cgi?id=22700#c3

<script type="worker" src="/path/to/worker.js"></script>
<script>
  document.querySelector("script[type='worker']").port.postMessage("hi");
</script>

To keep this orthogonal with the script/module dimension, this could be supported with an attribute:

<script worker src="/path/to/worker.js"></script>
<script>
  document.querySelector("script[worker]").port.postMessage("hi");
</script>

But I'm skeptical that this is worth additional HTML syntax, especially if we can make the JS API more ergonomic.

HTML, script, worker, source

Same as above but

<script type="worker">...</script>

or

<script worker>...</script>

HTML, script, sync, URL

<script src="/path/to/script.js"></script>

HTML, script, sync, source

<script>...</script>

HTML, module, worker, URL

Medium-term:

<script module worker src="/path/to/worker.js"></script>

Long-term:

<module worker src="/path/to/worker.js"></module>

Again, unclear whether workers merit HTML syntax.

HTML, module, worker, source

Medium-term:

<script module worker>...</script>

Long-term:

<module worker>...</module>

HTML, module, sync, URL

Medium-term:

<script module src="/path/to/module.js"></script>

Long-term:

<module src="/path/to/module.js"></module>

HTML, module, sync, source

Medium-term:

<script module>...</script>

Long-term:

<module>...</module>

JS, script, worker, URL

Today:

var worker = new Worker("/path/to/worker.js");
navigator.serviceWorker.register("/path/to/worker.js", ...).then(function(worker) { ... });
var sw = new SharedWorker("/path/to/worker.js");

Generalization:

var work = new Work({
  script: true,
  url: "/path/to/worker.js"
});

var worker = new Worker(work);
navigator.serviceWorker.register(work, ...).then(function(worker) { ... });
var sw = new SharedWorker(work);

JS, script, worker, source

var work = new Work({
  script: true,
  source: "console.log('hi from worker')"
});

var worker = new Worker(work);
navigator.serviceWorker.register(work, ...).then(function(worker) { ... });
var sw = new SharedWorker(work);

JS, script, sync, URL

eval and XMLHttpRequest

JS, script, sync, source

eval

JS, module, worker, URL

var work = new Work({
  url: "/path/to/worker.js"
});

var worker = new Worker(work);
navigator.serviceWorker.register(work, ...).then(function(worker) { ... });
var sw = new SharedWorker(work);

JS, module, worker, source

var work = new Work({
  source: "console.log('hi from worker')"
});

var worker = new Worker(work);
navigator.serviceWorker.register(work, ...).then(function(worker) { ... });
var sw = new SharedWorker(work);

JS, module, sync, URL

System.import

JS, module, sync, source

System.module

My Conclusions

  • The existence of Worker, SharedWorker, ServiceWorker, and possibly more in the future suggests that the only extension point possible is a new extensibility dimension in the argument (which currently coerces everything to a string). Hence: a new Work constructor that gets overloaded with DOMString. Not ideal for ergonomics but a step forward, and convenience wrappers (e.g. a spawn function) are still possible.
  • A worker attribute is possible but probably not advisable, especially given these additional dimensions like shared, service, etc.
  • A <script module> should ignore its type attribute entirely, always assuming 'application/javascript'. The <module> tag should be an alias for this, and in time should become the preferable development model. Medium-term apps that deploy to down-rev browsers can use <script type="x-es6" module> and do their own runtime transpiling.
  • The Work constructor should default to accepting a Module since that's generally more flexible than Script. However, we can't just make Worker et al accept Module in the future, since that's implicitly strict and likely to break the web. :'-(
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment