Crank.js, a JavaScript framework that uses generators for state

4 hours ago 1

import {renderer} from "@b9g/crank/dom";

import {Suspense} from "@b9g/crank/async";

function formatNumber(number, type) {

number = number.padEnd(16, "0");

if (type === "American Express") {

return [number.slice(0, 4), number.slice(4, 10), number.slice(10, 15)].join(" ");

}

return [

number.slice(0, 4),

number.slice(4, 8),

number.slice(8, 12),

number.slice(12),

].join(" ");

}

function CreditCard({type, expiration, number, owner}) {

return (

<div style="

padding: 10px;

margin: 10px 0;

display: grid;

grid-template-columns: repeat(2, 1fr);

grid-template-rows: repeat(2, 1fr);

border: 1px solid currentcolor;

border-radius: 10px;

">

<pre>{formatNumber(number, type)}</pre>

<pre>Exp: {expiration}</pre>

<pre>{type}</pre>

<pre>{owner}</pre>

</div>

);

}

async function *LoadingCreditCard() {

let count = 0;

const interval = setInterval(() => {

this.refresh(() => count++);

}, 250);

this.cleanup(() => clearInterval(interval));

for ({} of this) {

yield (

<CreditCard

number={"*".repeat(count) + "?".repeat(Math.max(0, 16 - count))}

type={"Loading" + ".".repeat(count % 4)}

owner="__ __"

expiration="__/__"

/>

);

}

}

async function MockCreditCard({throttle}) {

if (throttle) {

await new Promise((r) => setTimeout(r, 2000));

}

const res = await fetch("https://fakerapi.it/api/v2/creditCards?_quantity=1");

if (res.status === 429) {

return (

<marquee>Too many requests. Please use free APIs responsibly.</marquee>

);

}

const {data: [card]} = await res.json();

return (

<CreditCard

number={card.number}

type={card.type}

owner={card.owner}

expiration={card.expiration}

/>

);

}

function RandomCreditCard({throttle}) {

return (

<Suspense fallback={<LoadingCreditCard />}>

<MockCreditCard throttle={throttle} />

</Suspense>

);

}

function *CreditCardGenerator() {

let throttle = false;

const toggleThrottle = () => {

this.refresh(() => throttle = !throttle);

};

for ({} of this) {

yield (

<div>

<div>

<button onclick={() => this.refresh()}>

Generate new card

</button>

{" "}

<button onclick={toggleThrottle}>

{throttle ? "Unthrottle" : "Throttle"} API

</button>

</div>

<RandomCreditCard throttle={throttle} />

</div>

);

}

}

renderer.render(<CreditCardGenerator />, document.body);

Read Entire Article