Last active
March 2, 2020 13:08
-
-
Save davidchase/2f99911108a80ccf8ada988d8e82fcbf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://flems.io/#0=N4IgZglgNgpgziAXAbVAOwIYFsZJAOgAsAXLKEAGhAGMB7NYmBvAHhLID4AdNNmDACbc0AAhEs41AE4QADsRFwp1ALxcQJYrLiIA9LoCuaWQGsA5vjpZDaCPQC0xAJ6yYAAQAM+ACz4AjLoCEHDENnZoji4w+ABWcOocLLqSMvLCYkmE-EI8GQBGtAJO6eK6BUXCmaRQHJQgcDCw1MThCIggAEyIAGwAHCAAvhTo2LjtUBB5sQhUdAxMxHgQWLK0UgrAIlJMAjBSIgMiYFK0WCIA5JraejamFla67Lqy2xjNycQYaAIYUPTRWEKBlg03OPB4MAAHqt1kcjM1wkcTlgAKIANwWAApnK4KCJGjAcAwAJQiYC5LYwYgGKSiMDwlr0TFoKHEUnk0RifGwInEfCCATohYAGWCjBZUmxUTxLMhbIpAx4irQEOhawU9LQCPoIiwGFkmLAeKU1HZFO21NpcK1jLQzNZZs5YhNmLRvxEKg4IllxENrt+xMDCqV4NlMI1DMRnwNkLxYEdYjAmMhxPNVJpokhIZVYfV1u1ohwUjMMGTcATlMtdMjTJ9FbEkLg+G2AgM1FL0ZlDuDaGVqvD+dtRyp1EIQoYmJpUArFozg-C9rl9eHxFHk6k04pXJE+GIWTt2zgsg9XsPsmmTKDTq5u-3i-l17Elgwq8I99TnOVfdzsM1BaOtBQAIBpgGgeIQLYLS-MaygzumVp-kO75kluIiwAobzUB6IgQRAUFQKhPqYphH7bi6iELmiy5iJh2GgcR1DUHiVGoWIREkahAykQc2b9nmFE6ts3x7AAIgA8gAspiJrMRAMAAO54o0WBwVW861g6KHXuRNZ2j8nzUd6rKYkJuySmicnyZi+kYMSSlQCp3FiFxPbflCA5zCEOECNhkIniIWY5u5eaeRhUDyRgThwNhGD+Xk-kYKGwW-rpWxGNJsFac6yiYhAAgfm5aopTaiIhBg6wAOp4W+saKJlHJiLOCG6chDVckRKaoS6dauUlRURiVOrSPwjDjsQACCPzyHsmIVqFAXRSoIjIAAummanIH5noLfgYBrCibxvmA-lJimdlHP5jb4LIBhwEdxJrb2fUefQXmyC+hDYcRUhSHitB5DEpLbeVUjNjArbtpiDFMQFQNerRABkCMiJhm0rX9APEnUDRNLabQgAA7AAzIgBPdIMwwgJgOB4NMdRzOKiztMsA6bOwUAHEipwXFcOj6EYdyWKcjykM8rzvGV3y-P8+CAq2IJxGCtgrHmbXDS+MBjZN+qML95pGBQFJFiWhucqZomSabiaAcBVu6vqdu-BFUV2+9e5KlzZznPgugTHkSs8OhIgAJIidhHg8PNyCEF8AiwGJaAAMITNQJh4tQKcmGNcArdh6ujRiDDa9NkoflHMffPHScVybOHGAYxDZ7nS355rhcTVNuuzZHr0KNHsewCJ-x4gI-xN3nrwFwsxddx+PD6CIABqlk8AJojLwpmKbDZMqjAcqlzuzAAGqEsEEaIlNuoohIgrHiLIl-buIEE3Qo9CJzXMAqAAJMAFdxzABOH8vglkOG6KABgv6-2pjAQ4uhH4ZGeAg8QeQG7EB1O-TOP8-4D0AUnTOAwOCTR8hJNYMAkioOIOgtAyCWDAmQWIX+NlZb6kxHfbcuVGBYHAnDdhT9j58KfuICYgihEiEwRAVO2DZr+X-oPf4nDCTEmVGI1RIgTAwCcNgiAKi1FCJCE4WA2C2p6KEYwOUIkYB0CkC+cIiAcJcPwKPFkIgAD8FwJgskcIQE4BgzCEHOCIex5xzh21MU-agNI4BrGCasCCutQmiNUeY4gAAVGxaA4B7SkFgYJ1B9R4V+BAAAXjAJW4TtwDF0eEhhajf54UJLuPCsBqmmKSBMWp24T6Pi5Mou+SR6Gn0CBAC+FJunKgXgAVTdjAVeqUDCyH0qWMqjA8TvUMbQQQ2FNhvFtMEgA+oEriWVKxzhMSuUc9iZHbS3jufA+AVkwBHi+DA9jHlOJeULLUL5MTrL+IIfA4DIGki4mEkOAA5AACpM1JVy4YiFufch5nxVnelGPYv5myBCAt+JA-eYLE7CmDonAA0nC-yW875IseWCti6KLiJJ6TZN5KLojMLmPk30mwWjEFgCyjW+AYHgQEPYgA1KK0OI9-j2LAL8Bo+9OJ2VQuJcFKJyU3POU+e5NK77MsUKyj5nwWEGh8p6Ph2K8oehUEtTFAKgXREte4zYSKBBSpZPYgAhNi5xMBOb2IEHfJy+LUL7PVV6R5CpkC2uxbs8IK1u5PRzPNDAcBonUEhR9GKcUKXOvuRgZiuKYAYo+sRHFECnkiDyCCsuvcUaptoFhJasVtrxQ1Xc-kBby32Pii5NAC8JIYAgjwKQ6U0zCSkOJKSqE9pAQNHfBZSzaUnKEXq1AIgeV8ouMccGoSRA+plXKiteV7GhwOOjPhMDgnlKfkMO+xtSzID4XqA0Ka023NjfQYJKqURHPOj67OSqeliGfcRcKkU4DvoLMEwlxKSW-vTpnADS7gOsNEa+htGa9yQb2RcYOUKYW7vtfY5A5xPjFipLu849rzi51BaIl+Dds58KDWIFaQbAPbg3opVCo9Im8nwOUJwFIPwfnpqcWQ0A9h4DyBgPIjRsYEgLPjAmABORAfgCaDBWgMIAA |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://flems.io/#0=N4IgtglgJlA2CmIBcB2AzAOjWgNCAZhAgM7IDaoAdgIZiJIgYAWALmLCHgMYD2lL8fshAAeAEY8oATwB8AHUoACReICuLFn3lLligMKwIXANaKAsvAXKRAejHrNlbbYnSZnEMXgIuLCH1IGACYkAEYgkABfHCpaekYAK1JuPgEhBggwAAceACcWRWBFVnZFSMV8XJ4wRQByVhYs4iQbG1VKLOMAcwxeMBsSmyzc+GpfG2IWakooalg+eAwwSVUEDCTahQV8dt9-JXx4Fi4mAFEAN0EWAApVXNgASkKrRRGWO4Pdvz4Ko5OIShda6UeAADxYT2AL2Uh2OTFu9we0N0GBYTEE1xGxCyigAvDJXvBsetiHxrg8kTpdIpUejKMCwRDkcpetQ4QzwZTlJEFDzKApeJRJoowNQsgBBPY-XGKa4sKRZeA4RTEXJcJ74546N4fCpffYisVZAFAkGcrXU1Vca7nOZ4glQqm6M03eWK5W2x7IyJcsq8raUQXC4gIeA4mVgYj2xQggDuigAClVIF5MUSeLBLtHHcovCwACqZeA8dRp0mZpUi4iUn0BnaB75KKDeahSa6R5VWyEvHW5T4N-YciEW3Qh+Bh9vV2kY8nZ5kqtVD33c318vkCgIFAByAHkt6c8YoAMpSMASWDXWpbha1SkboUFBPUCC5Q-XajKsQagnXHOKD8vGIOAvPgkxILOmoAToxAzEgsrfooQEvKKWRwfg0ZPi+77Kvg1xfg8wE6GImRinB1z4MqXQIZhuTke+BGKEC+G8ne-KUPWUpKKoWSzAI1yTGylZkGMjbKlkrbzNQUAALrdtqRy6n+yj5gAkmYpxkdRz60cAGB6QJAjKn4dBweJUiSVA0SKLu+4EciegADIqXoADSmkYdp1zzkUekYAZlbQHB-kYNAigANSKKEZSEdSygoZKjaXgAYqc+Z6AAErUOF-Gclz8JeDRNC0NgjAAjliIWUDYYoQG0Xi5MQAD8zawK2uJoLey6KHZToACKnA54oAJopWl6XuZqNG-jS+lTIZii8dQQVzYsi29HwXBstcZkWRgi1PFZNmnD11KjRlE0ElN3kzX5K3Koty2CXtbLUOtgZbTtPBSc9UwHTFsXxZxXlOtStT9YNI2pRlWXzsoLWttcACsAAMqPZXCFxXAVGhFa0ZUVQC1XGm0lDGJQPCxlVQSdfOXWrsJnHSeS-psRxjYVMmmP5W6lbePAdD8HJyi9v2QMukLuh8wLLAYFJUBcywDkQJMgjwLRPPKuLLxrgG2z6j8+AZlAWTkZQyoAhAfhzMq8B5Sw1YjiLeoDmS4sjsoCAFGMXCHlNFtW7AypHV1bMGiMXB3KmXbu6Oi6h2SvkukeK0S7F-5cD7Mr4PS3sYKBNwMUnKewzGjLvhneeTOSXXUhA6Hl1wfkzLOACEuIysHMdp+HkfwA3TdQNXJd8mntZOiPug9w1fe21c1bayz97CtAVyW1Ih6gtGoIBkGXuwLGrZRjK1DRmI0bUHW+tKLk7T8WqEtWtcK-8GvNaXy7SibbAsAAOqW-CoIcIS1wqCX0Ttt6UHXOxK+Io1ZdD7qCB2f4nbx3pG7JSihEEYBGFAVQXA+5f1-v-TWjJVyL1ZjAqYJsKILnVI7BSfZnZi1ITHR+s9+BzhBhUa47CmRcJdDwu2XUx7cnIagxQs9chtg7BUSgEsUFXyXKwo4Kl+Bq09NcCCBIBHZ2rsqSMZDIEBhvvSF4VDgbUiDBmRY8wejEWblYtYtjlS1CoYqKAigSwsCQLef6MIjYm3nNxXiSprqBUUMje6L04JkGkkZIscFai1GivOQGiVaiOWci5LKHNqgK0vFwQwJgclQB4BHaWGBXBSApMiX0lJKS70NBKTiR9MFHwJPALexAd6bkUOcCA8B4wyhKLAAABmoDQPw+AGCMMYXEAASYAaT9jEGuGQDJTlXI5NqGdTKslIgyBmSYcw8AXAOC0KMnpD5FDBMEmYSQ3g3z+WVAzUSihPpSVkpw4WDClAYI2Vk2oF1ZS6VmoJKJUxHoCB+q9QUm0bgfKgA8ERfojFsUabvG+vhTj4E3jKHh+BDi+GIC8kS+wxISS+jJBCyDfkxx2VDTKwLYQnHybUO4sBbwLzRQoDwfRjQIFyMIMQ1AxDeA8F4HwjZAggGRkgZGABaUIAAWRG8qogxBADQOgwhejEGSCAQUaQWDCCiNJSIQA | |
import { html } from 'https://unpkg.com/htm/preact/standalone.module.js' | |
function fetchEvent(url) { | |
return function fetching(next) { | |
fetch(url) | |
.then(resp => resp.json()) | |
.then(next) | |
.catch(next) | |
} | |
} | |
const mapAction = (type, src) => { | |
return function mapping(next) { | |
src(val => { | |
next(type, val) | |
}) | |
} | |
} | |
const sleep = ms => new Promise(resolve => { | |
setTimeout(resolve, ms) | |
}) | |
function delay(ms, src) { | |
return function(next) { | |
sleep(ms).then(() => { | |
src(next) | |
}) | |
} | |
} | |
const NONE = Symbol('None') | |
const Pair = (a, b) => ({ | |
a, | |
b, | |
fst:() => a, | |
snd: () => b, | |
map: f => Pair(a, f(b)), | |
bimap: (f, g) => Pair(f(a), g(b)) | |
}) | |
function update(state, [action, payload]) { | |
return { | |
TIME: () => Pair({...state, time: payload}, NONE), | |
CLICK: () => Pair( | |
{ ...state, id: state.id + 1 }, | |
mapAction('FETCH', fetchEvent('https://reqres.in/api/users?delay=3')) | |
), | |
DELAYFETCH: () => Pair({ ...state, data: state.data.concat(payload.data) }, NONE), | |
FETCH: () => Pair( | |
{ ...state, data: state.data.concat(payload.data) }, | |
mapAction( | |
'DELAYFETCH', | |
delay(5000, fetchEvent('https://reqres.in/api/unknown/2')) | |
) | |
) | |
}[action]() | |
} | |
function fromEvent(type, element) { | |
return function(next) { | |
element.addEventListener(type, next) | |
} | |
} | |
function foldp(fn, initial, events) { | |
return function(next) { | |
let acc = Pair(initial, NONE) | |
function recurse(src) { | |
src(function(...nextState) { | |
acc = fn(acc.fst(), nextState) | |
next(acc.fst()) | |
if (acc.snd() !== NONE) { | |
recurse(acc.snd()) | |
} | |
}) | |
} | |
recurse(events) | |
} | |
} | |
const identity = x => x | |
const always = a => b => a | |
function run(src) { | |
src(identity) | |
} | |
function callWith(x, f) { | |
f(x) | |
return x | |
} | |
function merge(xs) { | |
return function(next) { | |
xs.reduce(callWith, next) | |
} | |
} | |
function tap(f, src) { | |
return function(next) { | |
src(event => { | |
f(event) | |
next(event) | |
}) | |
} | |
} | |
function every(ms, fn) { | |
return function(next) { | |
setInterval(() => next(fn()), ms) | |
} | |
} | |
run( | |
tap( | |
console.log.bind(console.log, 'tapped out:'), | |
foldp( | |
update, | |
{ id: 0, data: [], time: '' }, | |
mapAction('CLICK', fromEvent('click', document.body)) | |
) | |
) | |
) | |
const mapActions = xs => e => xs | |
const view = html`<button onClick=${mapActions(['CLICK', 'FETCH'])}>Click Me</button>` | |
const updateModel = (state, [action, payload]) => { | |
return { | |
'CLICK': () => ({...state, data: state.data.concat(payload)}) | |
} | |
} | |
const constructEfx = (effects, [action, payload]) => { | |
return { | |
'FETCH': () => fetchEvent('url') | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment