Skip to content

Instantly share code, notes, and snippets.

@dead-claudia
Last active May 29, 2018 07:33
Show Gist options
  • Save dead-claudia/389fc6f22d658986c73653a9bcd704f9 to your computer and use it in GitHub Desktop.
Save dead-claudia/389fc6f22d658986c73653a9bcd704f9 to your computer and use it in GitHub Desktop.
State driver for async generator-based storylines
// This is careful to avoid memory leaks. Also, it is written in pure
// ES5 assuming a Promise polyfill (so it works with transpiled code
// without needing transpiled) and the relevant Symbol polyfills.
function run(route, render, onError) {
"use strict"
if (onError == null) onError = function (e) { console.error(e) }
function run(next) {
var current = next.value
if (Array.isArray(current)) current = current[0]
var iter = current.route(current)[Symbol.asyncIterator]()
function init(next) {
if (next.done) return Promise.resolve(next)
return new Promise(function (resolve) {
var value = next.value
var memo = {value: undefined}
var send = function (x) {
memo.value = x
var func = resolve
if (func != null) { resolve = undefined; func(memo) }
}
if (typeof value === "function") {
var pair = value(send)
if (typeof pair[0] === "function") send = pair[0]
value = pair[1]
}
render(value, current, send)
})
.then(renderCont, renderFail)
}
function renderCont(memo) {
try {
if (current == null) {
return Promise.resolve(iter.return(memo.value)).catch(logFail)
} else {
return Promise.resolve(iter.next(memo.value)).then(init, logFail)
}
} catch (e) {
return logFail(e)
}
}
function logFail(e) {
onError(e)
return renderFail(e)
}
function renderFail(err) {
while (true) {
try {
return Promise.resolve(iter.throw(err)).then(init, renderFail)
} catch (e) {
onError(e)
err = e
}
}
}
try {
render("preload", route)
return Promise.resolve(iter.next()).then(init).then(run, onError)
} catch (e) {
onError(e)
}
}
return run({value: route})
}
function join(options) {
// TODO
}
async function *throttle() {
// TODO
}
// This is thrown.
var canceled = Symbol('canceled')
function openCancel() {
return async function *(func) {
// TODO
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment