Skip to content

Commit a656853

Browse files
committed
webcomponent attributes are now updating cells
1 parent 6ffa613 commit a656853

File tree

3 files changed

+46
-106
lines changed

3 files changed

+46
-106
lines changed

index.js

Lines changed: 27 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
// import { Runtime, Inspector, Library } from 'https://cdn.jsdelivr.net/npm/@observablehq/runtime@4.7.2/src/index.js' //@observablehq/runtime';
2-
3-
import {
4-
Runtime,
5-
Inspector,
6-
Library,
7-
} from 'https://cdn.jsdelivr.net/npm/@observablehq/runtime@4/dist/runtime.js';
1+
import { Runtime, Inspector, Library } from '@observablehq/runtime';
82

93
const staticAttrs = ['notebook', 'cell', 'class', 'style'];
104

@@ -43,14 +37,34 @@ class ObservablehqCell extends HTMLElement {
4337
this.init();
4438
}
4539
async init() {
46-
this._notebook = await this.importNotebook(this.notebook, this.injections);
47-
const generator = await this._notebook.cell(this.cell);
48-
if (!generator) return;
40+
// inspired by
41+
// https://observablehq.com/@mbostock/dataflow
42+
// https://observablehq.com/d/d0bb058f650143a9
43+
// load selected notebook definitions
44+
const { default: define } = await import(
45+
/^https:/.test(this.notebook)
46+
? this.notebook
47+
: `https://api.observablehq.com/${this.notebook}.js?v=3`
48+
);
49+
// create runtime with or not custom library
50+
const runtime = new Runtime(this.library);
51+
52+
// Create the main module, including any injected values.
53+
const main = runtime.module();
54+
for (const name in this.injections) {
55+
main.define(name, [], () => this.injections[name]);
56+
}
57+
const imported = runtime.module(define);
58+
this._notebook = imported.derive([...Object.keys(this.injections)], main);
4959

60+
if (!this.cell) {
61+
new Runtime(this.library).module(define, Inspector.into(this.wrapper));
62+
return;
63+
}
5064
try {
51-
const result = generator.next(); // yield generator
52-
const value = await result.value; // await cell value
53-
this.wrapper.appendChild(value); // append it to shadowelement root
65+
main
66+
.variable(new Inspector(this.wrapper))
67+
.import(this.cell, this._notebook);
5468
} catch (e) {
5569
console.error('cell name error', e);
5670
}
@@ -88,94 +102,6 @@ class ObservablehqCell extends HTMLElement {
88102
// setter converts it back to string
89103
this.setAttribute('injections', JSON.stringify(newValue));
90104
}
91-
// from https://observablehq.com/@mbostock/dataflow
92-
// https://observablehq.com/d/d0bb058f650143a9
93-
importNotebook(
94-
notebookSpecifier, // e.g., "@d3/bar-chart"
95-
injections = {} // e.g., {data: [{name, value}, …]}
96-
) {
97-
const promise = (async () => {
98-
// Create the main module, including any injected values.
99-
const runtime = new Runtime(this.library);
100-
const main = runtime.module();
101-
for (const name in injections) {
102-
main.define(name, [], () => injections[name]);
103-
}
104-
105-
// Load the requested notebook’s definition as an ES module.
106-
const { default: define } = await import(
107-
/^https:/.test(notebookSpecifier)
108-
? notebookSpecifier
109-
: `https://api.observablehq.com/${notebookSpecifier}.js?v=3`
110-
);
111-
112-
// Create the imported notebook’s module, and then derive a module
113-
// from it to inject the desired values. (If there are none, then
114-
// this is basically a noop.)
115-
const imported = runtime.module(define);
116-
const derived = imported.derive([...Object.keys(injections)], main);
117-
// return full notebook if no cells are presented
118-
119-
// In many cases the imported cell will only have a single value, but
120-
// we must use the most generic representation (an async generator) as
121-
// the imported cell may be an async generator, or may reference one.
122-
123-
derived.cell = (cellName) => {
124-
if (!cellName) {
125-
const runtime = new Runtime(this.library).module(
126-
define,
127-
Inspector.into(this.wrapper)
128-
);
129-
return;
130-
}
131-
return this.library.Generators.observe((notify) => {
132-
// Create the primary variable with an observer that will report the
133-
// desired cell’s fulfilled or rejected values.
134-
console.log("testt")
135-
main
136-
.variable({
137-
fulfilled(value) {
138-
notify(value);
139-
},
140-
rejected(value) {
141-
notify(Promise.reject(value));
142-
},
143-
})
144-
.import(cellName, derived);
145-
146-
// Lastly, when this generator is disposed, dispose the runtime to
147-
// ensure that any imported generators terminate.
148-
return () => runtime.dispose();
149-
});
150-
};
151-
152-
return derived;
153-
})();
154-
promise.cell = (cellName) =>
155-
promise.then((notebook) => notebook.cell(cellName));
156-
return promise;
157-
}
158-
159-
importCell(
160-
cellName, // e.g., "chart"
161-
notebookSpecifier, // e.g., "@d3/bar-chart"
162-
injections = {} // e.g., {data: [{name, value}, …]}
163-
) {
164-
return this.importNotebook(notebookSpecifier, injections).cell(cellName);
165-
}
166-
// observeAttrChange(el, callback) {
167-
// var observer = new MutationObserver((mutations) => {
168-
// mutations.forEach((mutation) => {
169-
// if (mutation.type === 'attributes') {
170-
// let newVal = mutation.target.getAttribute(mutation.attributeName);
171-
// callback(mutation.attributeName, newVal);
172-
// }
173-
// });
174-
// });
175-
// observer.observe(el, { attributes: true });
176-
// return observer;
177-
// }
178-
// Fires when an instance was removed from the document
179105
disconnectedCallback() {}
180106
static get observedAttributes() {
181107
return ['injections'];

rollup.config.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@ import resolve from 'rollup-plugin-node-resolve';
44
import babel from 'rollup-plugin-babel';
55
import json from 'rollup-plugin-json';
66

7+
const onwarn = function (warning, warn) {
8+
if (warning.code === 'CIRCULAR_DEPENDENCY') {
9+
return;
10+
}
11+
warn(warning);
12+
};
13+
714
export default [
815
{
916
input: 'index.js',
1017
plugins: [resolve(), json(), babel()],
18+
onwarn: onwarn,
1119
output: {
1220
extend: true,
1321
file: 'dist/observablehq-web-component.js',
@@ -17,10 +25,11 @@ export default [
1725
{
1826
input: 'index.js',
1927
plugins: [resolve(), json(), babel(), terser()],
28+
onwarn: onwarn,
2029
output: {
2130
extend: true,
2231
file: 'dist/observablehq-web-component.min.js',
2332
format: 'umd',
2433
},
25-
}
34+
},
2635
];

test/index.html

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,24 @@
99
<title>observablehq-web-component</title>
1010

1111
<link rel="stylesheet" href="styles.css" />
12-
<!-- <script src="../dist/observablehq-web-component.js" defer></script> -->
13-
<script src="../index.js" defer type="module"></script>
12+
<script src="../dist/observablehq-web-component.js" defer></script>
13+
<!-- <script src="../index.js" defer type="module"></script> -->
1414

1515
</head>
1616

1717
<body>
18+
<!-- multiple cells with inejectoons -->
19+
1820
<div class="flex">
1921
<o-cell class="flex-child" notebook="@d3/bar-chart" cell="chart" injections={"height":300,"color":"brown"}>
2022
</o-cell>
21-
<o-cell class="flex-child" notebook="@d3/bar-chart" cell="chart"></o-cell>
22-
<o-cell class="flex-child" notebook="@d3/bar-chart" cell="chart"></o-cell>
23+
<o-cell class="flex-child" notebook="@d3/bar-chart" cell="chart" injections={"height":400,"color":"red"}>
24+
</o-cell>
25+
<o-cell class="flex-child" notebook="@d3/bar-chart" cell="chart" injections={"color":"gray"}></o-cell>
2326
</div>
27+
<!-- viewof cell example -->
2428
<o-cell notebook="@observablehq/introduction-to-views" cell="viewof point"></o-cell>
29+
<!-- whole notebook example -->
2530
<o-cell notebook="@fil/synchronized-projections"></o-cell>
2631
</body>
2732

0 commit comments

Comments
 (0)