Runtime V3 modules

In this post, @mbostock suggests switching over to the runtime V3 modules in our exports.

Here are two issues I noticed with the v3 modules served by Observable; both are apparent if you compare this v3 module with the underlying notebook

  • First, the URLs to imported non-published notebooks are incorrect:
import define1 from "../3c69b22e8a78157b.js?v=3";

should be

import define1 from "../d/3c69b22e8a78157b.js?v=3";

or

import define1 from "./3c69b22e8a78157b.js?v=3";
  • Second, anonymous cells currently donā€™t appear in the served v3 module. This is fine for some uses, but it means that many cells wonā€™t be displayed if you try to use this to embed the notebook.

Apologies if these are already known issues. Thanks!

1 Like

Oops, fixed! Imports in v=3 now resolve correctly, and weā€™ve restored anonymous cells. (Weā€™d like to have a mode that includes only named cells in the future, since you canā€™t import anonymous cells into notebooks, but that should be an optional optimization rather than the default behavior.)

2 Likes

Thanks for the quick response!

Iā€™ve noticed an inconsistency between the way notebooks and the v1 runtime files treat multiple imports from the same notebook and the way the v3 runtime files do: Currently, if I have notebook A with multiple import statements referencing notebook B, all of the variables in these imports will come from the same namespace (module?) unless I use import...with. The v1 runtime module files served by the API reflect this behavior, but the v3 runtime module files served by the API do not.

I tried to document this behavior in my ā€œimports tips and tricksā€ notebook a while back, but Iā€™ve also updated the above scratch notebook with a simpler example. There are 3 import statements there:

import {aa as importeda} from '3c69b22e8a78157b'
import {aa as importeda2} from '3c69b22e8a78157b'
import {aa as importeda3} with {} from '3c69b22e8a78157b'

You can see that importeda === importeda2 is true and importeda === importeda3 is false.

Consistent with this, in the v1 runtime module served by the API, importeda and importeda2 are both imported from: "3c69b22e8a78157b" (which is module m1), whereas importeda3 is imported from: "647d897e243bbbe2@789/7" (which is module m2).

However, in the v3 runtime module, each of these variables is imported from a distinct module: importeda comes from child1, importeda2 comes from child2 and importeda3 comes from child3.

Iā€™m not able to reproduce this bug. If you try it out here, youā€™ll see that importeda = importeda2 with v3 (the true value):

Observableā€™s module resolution bootstraps from ES module resolution. So, because the ES imports resolve to identical values, runtime.module returns the same Observable module for each.

That said, we are generating redundant ES imports, but this should be harmless (other than a few wasted bytes) because they have identical paths.

https://api.observablehq.com/d/647d897e243bbbe2.js?v=3

1 Like

Ah, I should have actually tested thisā€¦ Sorry for the noise and thanks for the explanation!

Currently v3 sources have a leading comment containing the notebook URL and version. Is this comment part of the API? Can I expect it to exist in every v3 source?

No, the comment is not part of the API.

1 Like

What about the frontmatter lines in v1 / v2 notebooks? Are those guaranteed to stay?

No, the comments are not part of the API. But as a practical matter, I donā€™t expect we will be making any substantive changes to them, either.

1 Like