import { ElementVNode , Module , VNode , elementToVNode , init } from 'mostly-dom' ; import { Stream , drain , map , scan } from 'most' ; import { Subject , hold } from 'most-subject' ; import { Component } from '@motorcycle/run' ; import { DomSource } from './types' ; import { MotorcycleDomSource } from './DomSources' ; import { vNodeWrapper } from './vNodeWrapper' ; export type DomSinks = { readonly [ key ] : Stream < any > ; } & { view$ : Stream < VNode > ; } ; export interface DomSources { dom : DomSource ; } export interface DomComponent extends Component < DomSources , DomSinks > { } export function makeDomComponent ( rootElement , options = { modules : [ ] } ) { const modules = options . modules || [ ] ; const patch = init ( modules ) ; const rootVNode = elementToVNode ( rootElement ) ; const wrapVNodeInRootElement = vNodeWrapper ( rootElement ) ; return function Dom ( sinks ) : DomSources { const { view$ } = sinks ; const rootVNode$ = scan ( patch , rootVNode , map ( wrapVNodeInRootElement , view$ ) ) ; const rootElement$ = hold ( 1 , map ( vNodeToElement , rootVNode$ ) as any ) ; drain ( rootElement$ ) . catch ( ( err ) => console . error ( 'Error in DomComponent:' , err ) ) . then ( ( ) => console . log ( 'Dom Component has terminated' ) ) ; const dom = new MotorcycleDomSource ( rootElement$ , [ ] ) ; return { dom } ; } ; } function vNodeToElement ( vNode ) { return vNode . element ; } export interface DomDriverOptions { modules : Array < Module < Element > > ; }