Similar ideas to Concur UI lib #17
Replies: 2 comments 2 replies
-
I didn't realize you ported Concur to JavaScript! Did you notice anything specific the two libraries could learn from each other? |
Beta Was this translation helpful? Give feedback.
-
Concur-js is more of a proof of concept right now, the API and performance could certainly be better. Crank is probably more pragmatic for JS development and does things in a more JS idiomatic way. However, Concur's semantic model is very well developed and brings a bit more of a disciplined approach, which I think scales better in the long run. For example, Concur components have return values and can be combined with generic combinators. I took the time to convert the example from crank's README. Compare Concur's solution below which has reusable combinators combined with minimal app-specific code, with the much more stateful code using Crank - First we can define a generic combinator which throttles the output of a widget. This could go in a library of some kind. function throttle(timeout, widget) {
var isThrottled = false;
var timer = null;
var reset = () => {
isThrottled = false
timer = null
}
return async function*() {
var res = yield* widget()
while(isThrottled) {
res = yield* widget();
}
isThrottled = true
if(!timer) timer = setTimeout(reset, timeout);
return res;
}
} If we wrap this around a button with a timeout 2000, the button's click will only work after a 2 second timeout. const throttledButton = throttle(2000, async function* () {
yield* <button onClick>Show me another dog</button>
}) We can create another generic component which can show a loading indicator for any type of async action. This could also go in a library - function loader(axn, msg) {
return <div>{axn()}<div>{msg}</div></div>
} And wrap it around our Dog data loader. This component will fire off an ajax request, show a loading indicator and then show the dog image when complete - async function* RandomDog() {
// Get data
var data = yield* loader(async function*() {
var res = await fetch("https://dog.ceo/api/breeds/image/random")
return await res.json()
}, "Fetching a good boy...")
// Display picture
yield* displayView(
<a href={data.message}>
<img src={data.message} alt="A Random Dog" width="300" />
</a>)
} Finally, we want to compose a throttled button, and the random dog generator together. forever(() =>
<div>
{throttledButton()}
{RandomDog()}
</div>) |
Beta Was this translation helpful? Give feedback.
-
Hi, you might be interested in checking out my Concur UI library which takes these ideas to their logical extreme!
It was originally written for Haskell (https://github.com/ajnsit/concur), then Purescript (https://github.com/ajnsit/purescript-concur), and even Javascript (https://github.com/ajnsit/concur-js). But the Javascript port is more of a proof of concept. Perhaps we can figure out a way to collaborate on the JS version?
There is some documentation here - https://github.com/ajnsit/concur-documentation/blob/master/README.md
Beta Was this translation helpful? Give feedback.
All reactions