Published
Edited
Feb 9, 2019
Importers
Insert cell
Insert cell
class Root {
constructor({ lookup, dispatchFn }) {
this.lookup = lookup;
this.multi = defmulti(dispatchFn);
Object.defineProperties(this, {
_list: { value: [], writable: true }
});
}

get value() {
return this;
}

render(rootId, ctx) {
return this.multi.dispatch(ctx, this.lookup(rootId));
}

addView(dispatchVal, viewFn) {
return Generators.observe(next => {
next(
this.multi.addMethod(dispatchVal, (ctx, x) => {
const args =
this.resolveChildren(x, x => this.multi.dispatch(ctx, x)) || x;
return viewFn(ctx, args);
})
);
this.dispatchEvent(this);
return () => {
this.multi.removeMethod(dispatchVal);
this.dispatchEvent(this);
};
});
}

resolveChildren({ content, ...x }, transform = identity) {
if (content) {
if (checks.isArray(content)) {
x.content = content.map(id =>
this.resolveChildren({ content: id }, transform)
);
} else if (checks.isObject(content)) {
const out = {};
for (let k in content) {
out[k] = this.resolveChildren({ content: content[k] }, transform);
}
x.content = out;
} else {
return transform(this.lookup(content));
}
return x;
}
}

addEventListener(type, listener) {
if (this._list.includes(listener)) return;
this._list = [listener].concat(this._list);
}
removeEventListener(type, listener) {
this._list = this._list.filter(l => l !== listener);
}
dispatchEvent(event) {
const p = Promise.resolve(event);
this._list.forEach(l => p.then(l));
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more