Closed asg017 closed 4 years ago
New demo site for this PR deployed to unofficial-observablehq-compiler-demo-11.surge.sh !
To see the difference before/after with pre-fetching imported modules, open these two pages up side-by-side, and do hard refreshes on both and see when errors are thrown:
Overall this looks great! I'd also suggest updating README.md
.
Oops, I hit submit on that comment before I was completely ready. Slightly longer thoughts:
I think this refactoring makes a lot of sense, since one of the things that puzzled me the first time I looked at this project was why the returned define
function was async
. As you say, this also makes the behavior more consistent with api.observablehq.com's ESM define functions.
I think committing .prettierrc
would be helpful if you plan on using it consistently in the future. It's just one less thing for contributors to fuss about.
New demo site for this PR deployed to unofficial-observablehq-compiler-demo-11.surge.sh !
This PR does a few things, sorry for the big file changes:
.prettierrc
but since the codebase is small, idk how effective it'd becellsPromise
->createCellDefinition
.compile.notebook
to usecreateModuleDefintion
. Both functions were doing the same thing before.This change was needed because "regular" cells that depended on imported cells would error out saying
importCell is not defined
while the imported cells were being resolved. For example, say there was this module:So, the compiler would parse this module, then do a
createCellDefintion
on each cell. Creating the cell definition for x would take a long time - since it would have toimport()
the@user/big-notebook
ES module, then it would finally callmodule.import(x, other)
. This is an async process.For
y
, on the other hand, that would be defined beforemodule.import(x, other}
would be called, since regular cell definitions could be synchronous. So,module.define(y, ["x"], x => 'x is ${x}')
would be executed,x
wouldnt be defined yet, throwing thex is not defined
error.You could see this in our
test.html
pages - here's an example, notice how when I do a hard refresh, theRuntimeError: x is not defined
error is throw for cells that depend on imported cells.So, my solution is that before we return the
async function define(runtime, observer)
increateModuleDefintion
, we first loop through all the import cells, resolve the modules that they depend on, then save that in a map. For example,dependencyMap
could look like:So now, when call
createCellDefintion
on all the cells, there's no need for import cells to by asynchronous anymore (since they can just calldependencyMap.get(name)
), removing the error. Here's what the page looks like now, notice how there's noRuntimeError
when I refresh:Here are 2 side effects to this:
define1
-define7
are imported, no matter how they are used or not)compile.module
andcompile.notebook
now return promises, making them async. I don't think this is a big deal, though@bryangingechen would love to hear your thoughts on these changes! It (kindof) breaks the old
compile.module
andcompile.notebook
APIs, since they are now asynchronous, but I dont think that's too big of an issue. (and sorry for the large diff!)