import * as H from "@funkia/hareactive" ; import { combine , Either , left , right } from "@funkia/jabz" ; import { withEffectsP , catchE , IO } from "@funkia/io" ; import { elements as E , runComponent , component } from "../../src/index" ; const apiUrl = "http://api.zippopotam.us/us/" ; const fetchJSON = withEffectsP ( ( url ) => fetch ( url ) . then ( ( resp ) => resp . ok ? resp . json ( ) : Promise . reject ( "Not found" ) ) ) ; function fetchZip ( zip ) { return catchE ( ( err ) => IO . of ( left ( err ) ) , fetchJSON ( apiUrl + zip ) . map ( right ) ) ; } const isValidZip = ( s ) => s . match ( /^\d{5}$/ ) !== null ; type Place = { "place name" : string ; state : string ; } ; type ZipResult = { country : string ; places : Place [ ] ; } ; type ViewOut = { zipCode : H . Behavior < string > ; } ; const main = component < ViewOut > ( ( on , start ) => { const zipCodeChange = H . changes ( on . zipCode ) ; const [ validZipCodeChange , invalidZipCodeChange ] = H . split ( isValidZip , zipCodeChange ) ; const requests = validZipCodeChange . map ( fetchZip ) ; const results = start ( H . performStream ( requests ) ) ; const latestResult = start ( H . flatFuturesLatest ( results ) ) ; const status = start ( H . stepper ( "" , combine ( invalidZipCodeChange . mapTo ( "Not a valid zip code" ) , validZipCodeChange . mapTo ( "Loading ..." ) , latestResult . map ( ( r ) => r . match ( { left : ( ) => "Zip code does not exist" , right : ( res ) => `Valid zip code for ${ res . places [ 0 ] [ "place name" ] }` , } ) ) ) ) ) ; return [ E . span ( "Please type a valid US zip code: " ) , E . input ( { props : { placeholder : "Zip code" } , } ) . use ( { zipCode : "value" } ) , E . br , E . span ( status ) , ] ; } ) ; runComponent ( "#mount" , main ) ;