import { unstable_batchedUpdates } from "react-dom" ; import logger from "./logger" ; import { Event , Node , Store , WatchTree } from "./types" ; import { splitPath } from "./utils" ; export const subscribe = ( store , path , node ) => { let tree = store . watchTree ; tree . subs . add ( node ) ; if ( path . length === 0 ) { tree . esubs . add ( node ) ; return ; } path . forEach ( key => { if ( ! tree . children [ key ] ) { tree . children [ key ] = { subs : new Set ( ) , esubs : new Set ( ) , children : { } , } ; } tree = tree . children [ key ] ; tree . subs . add ( node ) ; } ) ; tree . esubs . add ( node ) ; } ; export const unsubscribe = ( store , path , node ) => { let tree = store . watchTree ; tree . subs . delete ( node ) ; if ( path . length === 0 ) { tree . esubs . delete ( node ) ; return ; } for ( const pathKey of path ) { const prev = tree ; tree = tree . children [ pathKey ] ; if ( node . unsubscribe ) { node . unsubscribe ( { name : node . name , compId : node . compId , } ) ; } tree . subs . delete ( node ) ; if ( tree . subs . size === 0 ) { delete prev . children [ pathKey ] ; break ; } } tree . esubs . delete ( node ) ; } ; export const get = ( universe , pathKey ) : any => splitPath ( pathKey ) . reduce ( ( x , y ) => x && x [ y ] , universe ) ; export const submitPatches = ( store , universe , event ) => { const callbacksSet = new Set < Node > ( ) ; const { patches } = event ; patches . forEach ( ( { path } ) => { let subtree = store . watchTree ; for ( let i = 0 ; i < path . length ; i += 1 ) { const key = path [ i ] ; if ( ! subtree . children [ key ] ) { break ; } subtree = subtree . children [ key ] ; Array . from ( i === path . length - 1 ? subtree . subs : subtree . esubs ) . forEach ( x => callbacksSet . add ( x ) ) ; } } ) ; const comps = { } ; const compIds = [ ] ; Array . from ( callbacksSet ) . sort ( ( x , y ) => x . compId - y . compId ) . forEach ( ( x ) => { if ( ! comps [ x . compId ] ) { compIds . push ( x . compId ) ; comps [ x . compId ] = { setState : x . setState , status : x . status , name : x . name , newValues : { } , } ; } comps [ x . compId . toString ( ) ] . newValues [ x . pathKey ] = get ( universe , x . pathKey ) ; } ) ; logger . info ( "[update cycle]" , comps ) ; event . rerender = { } ; unstable_batchedUpdates ( ( ) => Object . keys ( comps ) . forEach ( compId => { const { setState , name , newValues , status } = comps [ compId ] ; if ( ! status . unmounted ) { event . rerender ! [ comps [ compId ] . name ] = true ; logger . info ( `[upcoming state update] ${ name }` , newValues , status ) ; setState ( newValues ) ; } } ) ) ; } ;