import type { ISubscribable , ISubscriber } from "@thi.ng/rstream" ; import { sidechainPartitionRAF } from "@thi.ng/rstream/sidechain-partition" ; import { subscription } from "@thi.ng/rstream/subscription" ; import { sync } from "@thi.ng/rstream/sync" ; import { updateDOM } from "@thi.ng/transducers-hdom" ; import { autoObj } from "@thi.ng/transducers/auto-obj" ; import { map } from "@thi.ng/transducers/map" ; import { reducer } from "@thi.ng/transducers/reduce" ; import { scan } from "@thi.ng/transducers/scan" ; import { vals } from "@thi.ng/transducers/vals" ; const ctx = { ui : { root : { class : "pa2" , } , button : { class : "w4 h2 bg-black white bn br2 mr2 pointer" , } , } , } ; param root param tree param ctx const domUpdate = ( root , tree , ctx ? ) => sidechainPartitionRAF ( tree ) . transform ( updateDOM ( { root , ctx } ) ) ; param ctx param onclick param body const button = ( ctx , onclick , body ) => [ "button" , { ... ctx . ui . button , onclick } , body , ] ; param _ param stream const clickButton = ( _ , stream ) => [ button , ( ) => stream . next ( true ) , stream . deref ( ) , ] ; param _ param counters const resetButton = ( _ , counters ) => [ button , ( ) => counters . forEach ( ( c ) => c . next ( false ) ) , "reset" , ] ; param start param step const counter = ( start , step ) => { const s = subscription < boolean , number > ( undefined , { xform : scan ( reducer ( ( ) => start , ( x , y ) => ( y ? x + step : start ) ) ) , } ) ; s . next ( false ) ; return s ; } ; param initial const app = ( ctx , initial ) => { const counters = initial . map ( ( [ start , step ] ) => counter ( start , step ) ) ; return sync ( { src : autoObj ( "" , counters . map ( ( c ) => c . transform ( map ( ( ) => [ clickButton , c ] ) ) ) ) , xform : map ( ( buttons ) => [ "div" , ctx . ui . root , ... vals ( buttons ) , [ resetButton , counters ] , ] ) , reset : false , } ) ; } ; domUpdate ( document . getElementById ( "app" ) ! , app ( ctx , [ [ 10 , 1 ] , [ 20 , 5 ] , [ 30 , 10 ] , ] ) , ctx ) ;