import * as React from "react" ; import { kernels } from "rx-jupyter" ; import { ServerConfig } from "../host-storage" ; import Host from "./host" ; interface KernelAllocatorProps { children ? : React . ReactNode ; host : ServerConfig ; kernelName : string ; cwd : string ; } interface KernelAllocatorState { channels : object | null ; error : boolean ; } const { Provider , Consumer } = React . createContext < KernelAllocatorState | null > ( null ) ; export { Consumer } ; class KernelAllocator extends React . Component < KernelAllocatorProps , KernelAllocatorState > { allocate = ( ) => { const { kernelName , host , cwd } = this . props ; const { endpoint , token } = this . props . host ; kernels . start ( host , kernelName , cwd ) . subscribe ( xhr => { this . setState ( ( _prevState , currentProps ) => { if ( currentProps . kernelName !== kernelName || currentProps . cwd !== cwd || currentProps . host . endpoint !== endpoint || currentProps . host . token !== token ) { console . log ( "Props changed while in the middle of starting a kernel, assuming that another kernel is starting up" ) ; return { channels : null , error : true } ; } return { channels : kernels . connect ( host , xhr . response . id ) , error : false } ; } ) ; } , err => { console . error ( err ) ; this . setState ( { error : true } ) ; } ) ; } ; componentDidMount ( ) { this . allocate ( ) ; } componentDidUpdate ( prevProps ) { if ( prevProps . kernelName !== this . props . kernelName || prevProps . cwd !== this . props . cwd || prevProps . host . endpoint !== this . props . host . endpoint || prevProps . host . token !== this . props . host . token ) { this . allocate ( ) ; } } render ( ) { if ( ! this . props . children ) { return null ; } return < Provider value = { this . state } > { this . props . children } < /Provider>; } } interface KernelProps { children ? : React . ReactNode ; repo : string ; gitRef ? : string ; binderURL ? : string ; kernelName : string ; cwd : string ; } export default class Kernel extends React . Component < KernelProps > { static Consumer = Consumer ; static defaultProps = { repo : "nteract/vdom" , gitRef : "master" , binderURL : "https://mybinder.org" , kernelName : "python" , cwd : "/" } ; render ( ) { if ( ! this . props . children ) { return null ; } return ( < Host repo = { this . props . repo } gitRef = { this . props . gitRef } binderURL = { this . props . binderURL } > { } < Host . Consumer > { host => host ? ( < KernelAllocator kernelName = { this . props . kernelName } cwd = { this . props . cwd } host = { host } > { this . props . children } < /KernelAllocator>) : null} < /Host.Consumer> < /Host>); } }