Public
Edited
Dec 13, 2023
1 fork
12 stars
Insert cell
Insert cell
Insert cell
Insert cell
`we can create single line strings`
Insert cell
`but they can also
stretch over multiple lines`
Insert cell
`we can also interpolate an ${"ARBITRARY EXPRESSION".toLowerCase()} into these template literals`
Insert cell
Insert cell
function ourTagFunction(string, ...args) {
// can capture interpolation data...
// ...and return arbitrary data
return { string, args };
}
Insert cell
ourTagFunction`can intercept ${"arbitrary"} interpolations of ${"expression"}s and return arbitrary data`
Insert cell
Insert cell
dot`digraph { "parse GraphViz DOT" -> "return SVG"; }`
Insert cell
// this implements a fullblown HTML parser (https://github.com/observablehq/htl)
htl.html`
<form>
<label>
${["parse HTML", "and return HTML elements"].map((entry) => htl.html`<button>${entry}</button>`)}
</form>
`
Insert cell
tex`\text{or parse} ~ \TeX \wedge \text{return HTML elements}`
Insert cell
Insert cell
Insert cell
Insert cell
xs[Symbol.iterator]()
Insert cell
Insert cell
Insert cell
{
const iter = xs[Symbol.iterator]();
return [iter.next(), iter.next(), iter.next(), iter.next()];
}
Insert cell
Insert cell
Insert cell
function* generator() {
yield 1;
yield 2;
yield 3;
return "return";
}
Insert cell
Insert cell
{
const gen = generator();
return [gen.next(), gen.next(), gen.next(), gen.next()];
}
Insert cell
Insert cell
Insert cell
function* echo() {
/* resume next(0) -> */
const a = /* resume next(1) <- suspension point */ yield undefined;
const b = /* resume next(2) <- suspension point */ yield a;
const c = /* resume next(3) <- suspension point */ yield b;
return { a, b, c };
}
Insert cell
{
const gen = echo();
return [gen.next(0), gen.next(1), gen.next(2), gen.next(3) ];
}
Insert cell
Insert cell
Insert cell
[...generator()]
Insert cell
Insert cell
function* anotherGenerator() {
yield* [4, 5, 6];
}
Insert cell
[...anotherGenerator()]
Insert cell
Insert cell
function* yetAnotherGenerator() {
yield "prior";
const lvalue = yield* generator();
yield "interleave";
yield lvalue;
}
Insert cell
[...yetAnotherGenerator()]
Insert cell
function* asyncGenerator() {
yield 1;
yield Promises.delay(2000).then(() => 2);
yield Promises.delay(3000).then(() => 3);
yield 4;
yield Promises.delay(5000).then(() => 5);
}
Insert cell
asyncGenerator()
Insert cell
[...asyncGenerator()]
Insert cell
Insert cell
async function* accumulate(g) {
const xs = [];

for await (const v of g) {
xs.push(v);
yield xs;
}
}
Insert cell
Insert cell
accumulate(asyncGenerator())
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
async function* paginateGithubAPI(url, pageLimit) {
do {
const result = await fetch(url);
yield result.json();

const linkHeader = result.headers.get("link");
if (!linkHeader) return;
url = linkHeader.match(captureNextPageLink)[1];
} while (--pageLimit);
}
Insert cell
Insert cell
Insert cell
pages = accumulate(
paginateGithubAPI(
"https://api.github.com/orgs/github/repos",
/*pageLimit=*/ 10
)
)
Insert cell
Insert cell
Insert cell
function makeChannel() {
let input;
// https://github.com/observablehq/stdlib/blob/main/src/generators/observe.js
const output = Generators.observe((change) => {
input = change;
});

return { input, output };
}
Insert cell
chan = makeChannel()
Insert cell
chan.input(Date.now())
Insert cell
Insert cell
accumulate(chan.output)
Insert cell
Insert cell
Insert cell
target = ({
key: "value"
})
Insert cell
Insert cell
handler = ({
get(target, prop) {
return { target, prop };
}
})
Insert cell
Insert cell
debugProxy = new Proxy(target, handler)
Insert cell
debugProxy.key
Insert cell
debugProxy.arbitrary
Insert cell
Insert cell
validator = ({
set(obj, prop, value) {
if (prop === "age") {
if (!Number.isInteger(value)) {
// Indicate failure
return false;
}
if (value > 200) {
throw new RangeError("The age seems invalid");
}
}

// The default behavior to store the value
obj[prop] = value;

// Indicate success
return true;
}
})
Insert cell
user = new Proxy({ age: 30 }, validator)
Insert cell
(user.age = 53)
Insert cell
(user.age = "young")
Insert cell
(user.age = 201)
Insert cell
Insert cell
function range(start, finish) {
function* go() {
for (; start < finish; ++start) {
yield start;
}

return;
}

const handler = {
has(target, key) {
return start <= key && key < finish;
}
};

return new Proxy(go(), handler);
}
Insert cell
5 in range(1, 10)
Insert cell
Insert cell
Promises.delay(1000).then(() => 1)
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