|
1 | 1 | import{assert}from'chai' |
2 | 2 | import{ROOT_STATE_KEY,ACTION_PREFIX,IDLESTATUS_ACTIVE}from'./constants' |
3 | 3 | import{getActiveEvents,getUseFastState,getUseLocalState,getUseWebRTCState,getUseWebSocketsState,getThresholds,getLevel}from'./defaults' |
4 | | - |
5 | | -importconfigureContextfrom'redux-addons/lib/context' |
6 | | -import{createLogger}from'redux-addons/lib/log' |
7 | | -constnoop=()=>{} |
| 4 | +import{translateBlueprintsWith,translateBlueprintTypesWith}from'redux-blueprint' |
8 | 5 |
|
9 | 6 | constvalidateContext=(libContext,appContext)=>{ |
10 | 7 | assert.ok(libContext,'must pass opts to validate') |
@@ -55,3 +52,82 @@ export default function createContext({ appName |
55 | 52 | constappOpts={ appName,IDLE_STATUSES, idleStatusDelay, activeStatusAction, idleStatusAction, activeEvents, useFastStore, useLocalStore, useWebRTCState, useWebSocketsState, thresholds, level} |
56 | 53 | returnconfigureContext(libOpts)(appOpts) |
57 | 54 | } |
| 55 | + |
| 56 | +constcleanActionName=name=>name.toUpperCase().replace(/-+\s+/,'_') |
| 57 | + |
| 58 | +/** Validates library creators options */ |
| 59 | +constvalidateLibOpts=libOptsRaw=>{ |
| 60 | +assert.ok(libOptsRaw,'libOpts definition is required') |
| 61 | +const{ libName, validateContext, configureAppContext, configureInitialState}=libOptsRaw |
| 62 | +assert(typeoflibName==='string','libName must be a string') |
| 63 | +assert(libName.length>0,'libName must not be empty') |
| 64 | + |
| 65 | +assert.ok(validateContext,'validateContext must exist') |
| 66 | +assert(typeofvalidateContext==='function','validateContext must be a function') |
| 67 | + |
| 68 | +assert.ok(configureAppContext,'configureAppContext must exist') |
| 69 | +assert(typeofconfigureAppContext==='function','configureAppContext must be a function') |
| 70 | + |
| 71 | +assert.ok(configureInitialState,'configureInitialState must exist') |
| 72 | +assert(typeofconfigureInitialState==='function','configureInitialState must be a function') |
| 73 | +} |
| 74 | + |
| 75 | +/** Validates library consumers options */ |
| 76 | +constvalidateAppOpts=appOptsRaw=>{ |
| 77 | +assert.ok(appOptsRaw,'appOpts are required') |
| 78 | +const{ appName}=appOptsRaw |
| 79 | + |
| 80 | +assert(typeofappName==='string','appName opt must be a string') |
| 81 | +assert(appName.length>0,'appName opt must not be empty') |
| 82 | +} |
| 83 | + |
| 84 | +functionconfigureContext(libOpts){ |
| 85 | +constisDev=process.env.NODE_ENV!=='production' |
| 86 | +if(isDev)validateLibOpts(libOpts) |
| 87 | +const{ libName, validateContext, configureAppContext, configureInitialState}=libOpts |
| 88 | +returnappOpts=>{ |
| 89 | +if(isDev)validateAppOpts(appOpts) |
| 90 | +const{ appName, level}=appOpts |
| 91 | + |
| 92 | +consttranslateBlueprintType=blueprintType=>`${cleanActionName(libName)}_${cleanActionName(appName)}_${cleanActionName(blueprintType)}` |
| 93 | +consttranslateBlueprintTypes=translateBlueprintTypesWith(translateBlueprintType) |
| 94 | +consttranslateBlueprints=translateBlueprintsWith(translateBlueprintType) |
| 95 | + |
| 96 | +constlibContext={log:createLogger({ libName, level}) |
| 97 | +, libName |
| 98 | +, appName |
| 99 | +, translateBlueprintTypes |
| 100 | +, translateBlueprints |
| 101 | +} |
| 102 | + |
| 103 | +constappContext=configureAppContext(libContext)(appOpts) |
| 104 | +if(isDev)validateContext(libContext,appContext) |
| 105 | + |
| 106 | +returnObject.assign(appContext,libContext,{getinitialState(){returnconfigureInitialState(libContext)(appContext)} |
| 107 | +}) |
| 108 | +} |
| 109 | +} |
| 110 | + |
| 111 | + |
| 112 | +constnoop=()=>{} |
| 113 | + |
| 114 | +functioncreateLogger({ libName, level}){ |
| 115 | +const_formatMessage=({ level, message, obj})=>{ |
| 116 | +if(!message&&typeofobj==='string'){ |
| 117 | +message=obj |
| 118 | +obj=noop() |
| 119 | +} |
| 120 | +return_formatLog(obj ?`${level}: '${message}' =>${JSON.stringify(obj)}` :`${level}: '${message}'`) |
| 121 | +} |
| 122 | + |
| 123 | +const_formatLog=message=>`${libName} |${message}` |
| 124 | + |
| 125 | +returnprocess.env.NODE_ENV!=='production' ?( |
| 126 | +{trace:(obj,message)=>level==='trace' ?console.trace(_formatMessage({level:'trace', message, obj})):noop() |
| 127 | +,debug:(obj,message)=>['trace','debug'].includes(level) ?console.log(_formatMessage({level:'debug', message, obj})) :noop() |
| 128 | +,info:(obj,message)=>['trace','debug','info'].includes(level) ?console.info(_formatMessage({level:'info', message, obj})) :noop() |
| 129 | +,warn:(obj,message)=>['trace','debug','info','warn'].includes(level) ?console.warn(_formatMessage({level:'warn', message, obj})) :noop() |
| 130 | +,error:(obj,message)=>['trace','debug','info','warn','error'].includes(level) ?console.error(_formatMessage({level:'error', message, obj})) :noop() |
| 131 | +} |
| 132 | +) :({trace:noop,debug:noop,info:noop,warn:noop,error:noop}) |
| 133 | +} |