// let A = input(100),
// B = input(200),
// C = formula(console.log)(A, B);
// console.log("Setting A and B in succession")
// A.set(A.value + 1);
// B.set(B.value + 1);
// setTimeout(() => transaction(() => {
// console.log("Setting A and B in a transaction")
// A.set(A.value + 1);
// B.set(B.value + 1);
// }), 1000);
// class Table extends Vertex {
// constructor(columnNames) {
// this.columnNames = columnNames;
// this.rows = new Map();
// this.lastAdded = new Set();
// this.lastRemoved = new Set();
// }
// insert(values) {
// // TODO JSON encode values and set rows to [...values] => {col1: val1...}
// // Populate .lastAdded if appropriate
// // TODO Might need to modify propagate to call .flush or similar on walked, to clear lastAdded
// // and lastRemoved after a propagation cycle
// // TODO values can be Refs
// return this;
// }
// select(columnNames, wherePredicate) {
// // TODO
// // Return a View wired up to this table to receive updates
// }
// sum(columnName) {
// // TODO
// // Return a Formula
// }
// }
// class View extends Vertex {
// }
// A
// / \
// B C--F--Q
// \ / \/
// D E
// let A = new Input(0),
// B = new Formula([A], () => {
// console.log("B updated");
// }),
// C = new Formula([A], () => {
// console.log("C updated");
// }),
// D = new Formula([B, C], () => {
// console.log("D updated");
// }),
// E = new Formula([C], () => {
// console.log("E updated");
// }),
// Q = new Input(0),
// F = new Formula([C, E, Q], () => {
// console.log("F updated");
// });