2016-11-29 18:53:31 +09:00
import { compose } from 'react-apollo' ; // note: at the moment, compose@react-apollo === compose@redux ; see https://github.com/apollostack/react-apollo/blob/master/src/index.ts#L4-L7
2016-11-29 11:35:20 +09:00
2017-01-18 15:11:31 +01:00
export const Components = { } ; // will be populated on startup (see nova:routing)
export const ComponentsTable = { } // storage for infos about components
2016-11-29 11:35:20 +09:00
/ * *
* Register a Telescope component with a name , a raw component than can be extended
* and one or more optional higher order components .
*
* @ param { String } name The name of the component to register .
* @ param { React Component } rawComponent Interchangeable / extendable component .
* @ param { ... Function } hocs The HOCs to compose with the raw component .
*
* Note : when a component is registered without higher order component , ` hocs ` will be
* an empty array , and it ' s ok !
* See https : //github.com/reactjs/redux/blob/master/src/compose.js#L13-L15
2017-01-18 12:51:10 +01:00
*
* @ returns Structure of a component in the list :
*
2017-01-18 15:11:31 +01:00
* ComponentsTable . Foo = {
2017-01-18 12:51:10 +01:00
* name : 'Foo' ,
* hocs : [ fn1 , fn2 ] ,
* rawComponent : React . Component ,
* call : ( ) => compose ( ... hocs ) ( rawComponent ) ,
* }
*
2016-11-29 11:35:20 +09:00
* /
2016-12-06 18:06:29 +01:00
export const registerComponent = ( name , rawComponent , ... hocs ) => {
2016-11-29 11:35:20 +09:00
// console.log('// registering component');
// console.log(name);
// console.log('raw component', rawComponent);
// console.log('higher order components', hocs);
2017-01-18 15:11:31 +01:00
// store the component in the table
ComponentsTable [ name ] = {
2017-01-18 12:51:10 +01:00
name ,
rawComponent ,
hocs ,
} ;
2016-11-29 11:35:20 +09:00
} ;
/ * *
2016-12-12 16:48:49 +09:00
* Get a component registered with registerComponent ( name , component , ... hocs ) .
2016-11-29 11:35:20 +09:00
*
* @ param { String } name The name of the component to get .
* @ returns { Function | React Component } A ( wrapped ) React component
* /
2017-01-18 12:51:10 +01:00
export const getComponent = ( name ) => {
2017-01-30 19:46:48 +09:00
const component = ComponentsTable [ name ] ;
2017-02-19 16:10:21 +01:00
if ( ! component ) {
throw new Error ( ` Component ${ name } not registered. ` )
}
2017-01-30 19:46:48 +09:00
const hocs = component . hocs . map ( hoc => Array . isArray ( hoc ) ? hoc [ 0 ] ( hoc [ 1 ] ) : hoc ) ;
return compose ( ... hocs ) ( component . rawComponent )
2016-11-29 11:35:20 +09:00
} ;
2017-01-18 12:51:10 +01:00
/ * *
* Populate the lookup table for components to be callable
2017-01-18 15:11:31 +01:00
* ℹ ️ Called once on app startup
2017-01-18 12:51:10 +01:00
* * /
2017-01-18 15:11:31 +01:00
export const populateComponentsApp = ( ) => {
2017-01-18 12:51:10 +01:00
// loop over each component in the list
2017-01-18 15:11:31 +01:00
Object . keys ( ComponentsTable ) . map ( name => {
2017-01-18 12:51:10 +01:00
// populate an entry in the lookup table
Components [ name ] = getComponent ( name ) ;
// uncomment for debug
// console.log('init component:', name);
} ) ;
}
2016-11-29 11:35:20 +09:00
/ * *
2016-12-12 16:48:49 +09:00
* Get the * * raw * * ( original ) component registered with registerComponent
2016-11-29 11:35:20 +09:00
* without the possible HOCs wrapping it .
*
* @ param { String } name The name of the component to get .
* @ returns { Function | React Component } An interchangeable / extendable React component
* /
2016-12-06 18:06:29 +01:00
export const getRawComponent = ( name ) => {
2017-01-18 15:11:31 +01:00
return ComponentsTable [ name ] . rawComponent ;
2016-11-29 11:35:20 +09:00
} ;
/ * *
* Replace a Telescope component with the same name with a new component or
* an extension of the raw component and one or more optional higher order components .
* This function keeps track of the previous HOCs and wrap the new HOCs around previous ones
*
* @ param { String } name The name of the component to register .
* @ param { React Component } rawComponent Interchangeable / extendable component .
* @ param { ... Function } hocs The HOCs to compose with the raw component .
2017-01-18 15:11:31 +01:00
* @ returns { Function | React Component } A component callable with Components [ name ]
2016-11-29 11:35:20 +09:00
*
* Note : when a component is registered without higher order component , ` hocs ` will be
* an empty array , and it ' s ok !
* See https : //github.com/reactjs/redux/blob/master/src/compose.js#L13-L15
* /
2016-12-06 18:06:29 +01:00
export const replaceComponent = ( name , newComponent , ... newHocs ) => {
2017-01-18 15:11:31 +01:00
const previousComponent = ComponentsTable [ name ] ;
2016-11-29 11:35:20 +09:00
// xxx : throw an error if the previous component doesn't exist
// console.log('// replacing component');
// console.log(name);
// console.log(newComponent);
// console.log('new hocs', newHocs);
// console.log('previous hocs', previousComponent.hocs);
2016-12-06 18:06:29 +01:00
return registerComponent ( name , newComponent , ... newHocs , ... previousComponent . hocs ) ;
} ;
2016-12-10 21:58:40 +09:00
export const copyHoCs = ( sourceComponent , targetComponent ) => {
return compose ( ... sourceComponent . hocs ) ( targetComponent ) ;
}