Published
Edited
Dec 14, 2020
1 fork
Insert cell
Insert cell
{
const ref1 = new AdaptonRef()
const ref2 = new AdaptonRef()
const cell1 = new Adapton(async () => {
function $(ref1, ref2) {
return ref1 + ref2
}
const $$ = await Promise.all([
ref1.compute(),
ref2.compute(),
])
return $(...$$)
})
addEdge(cell1, ref1)
addEdge(cell1, ref2)
ref1.set(2)
ref2.set(3)
yield await cell1.compute()
ref2.set(7)
yield await cell1.compute()
}
Insert cell
class Adapton {
constructor(thunk) {
this._thunk = thunk
this._promise = Promise.resolve(null)
this._isClean = false
this._childAdaptons = new Set()
this._parentAdaptons = new Set()
}
dirty() {
if (this._isClean) {
this._isClean = false
for (const parentAdapton of this._parentAdaptons) {
parentAdapton.dirty()
}
}
}
async compute() {
if (this._isClean) {
return await this._promise
}
this._isClean = true
this._promise = this._thunk()
return this.compute()
}
}
Insert cell
class AdaptonRef extends Adapton {
constructor(value) {
super(async () => await this._promise)
this._promise = Promise.resolve(value)
this._isClean = false
}
set(value) {
this._promise = Promise.resolve(value)
this.dirty()
}
}
Insert cell
function addEdge(parentAdapton, childAdapton) {
parentAdapton._childAdaptons.add(childAdapton)
childAdapton._parentAdaptons.add(parentAdapton)
}
Insert cell
function removeEdge(parentAdapton, childAdapton) {
parentAdapton._childAdaptons.delete(childAdapton)
childAdapton._parentAdaptons.delete(parentAdapton)
}
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