-
async function importCell(
cell, // e.g., "chart"
notebook, // e.g., "@d3/bar-chart" or "8d5ef3030dfd3bad"
+
function importNotebook(
notebookSpecifier, // e.g., "@d3/bar-chart"
injections = {} // e.g., {data: [{name, value}, …]}
) {
+
const promise = (async () => {
// Create the main module, including any injected values.
const runtime = new Runtime();
const main = runtime.module();
for (const name in injections) {
main.define(name, [], () => injections[name]);
}
-
// Create the main module, including any injected values.
const runtime = new Runtime();
const main = runtime.module();
for (const name in injections) {
main.define(name, [], () => injections[name]);
}
+
// Load the requested notebook’s definition as an ES module.
const {default: define} = await import(/^https:/.test(notebookSpecifier)
? notebookSpecifier
: `https://api.observablehq.com/${notebookSpecifier}.js?v=3`);
-
// Load the requested notebook’s definition as an ES module.
const origin = `https://api.observablehq.com`;
const {default: define} = await import(
/^@[0-9a-z_-]+\/[0-9a-z_-]+(\/\d+)?([@~]|$)/.test(notebook += "") ? `${origin}/${notebook}.js?v=3`
: /^[0-9a-f]{16}([@~]|$)/.test(notebook) ? `${origin}/d/${notebook}.js?v=3`
: notebook);
+
// Create the imported notebook’s module, and then derive a module
// from it to inject the desired values. (If there are none, then
// this is basically a noop.)
const imported = runtime.module(define);
const derived = imported.derive([...Object.keys(injections)], main);
-
// Create the imported notebook’s module, and then derive a module
// from it to inject the desired values. (If there are none, then
// this is basically a noop.)
const imported = runtime.module(define);
const derived = imported.derive([...Object.keys(injections)], main);
+
// In many cases the imported cell will only have a single value, but
// we must use the most generic representation (an async generator) as
// the imported cell may be an async generator, or may reference one.
derived.cell = (cellName) =>
Generators.observe((notify) => {
// Create the primary variable with an observer that will report the
// desired cell’s fulfilled or rejected values.
main.variable({
fulfilled(value) { notify(value); },
rejected(value) { notify(Promise.reject(value)); }
}).import(cellName, derived);
-
// In many cases the imported cell will only have a single value, but
// we must use the most generic representation (an async generator) as
// the imported cell may be an async generator, or may reference one.
return Generators.observe((notify) => {
+
// Lastly, when this generator is disposed, dispose the runtime to
// ensure that any imported generators terminate.
return () => runtime.dispose();
});
-
// Create the primary variable with an observer that will report the
// desired cell’s fulfilled or rejected values.
main.variable({
fulfilled(value) { notify(value); },
rejected(value) { notify(Promise.reject(value)); }
}).import(cell, derived);
// Lastly, when this generator is disposed, dispose the runtime to
// ensure that any imported generators terminate.
return () => runtime.dispose();
});
+
return derived;
})();
promise.cell = cellName => promise.then(notebook => notebook.cell(cellName))
return promise;