@@ -210,85 +210,89 @@ const normalize = <T extends Settings>(
210210
211211interface LocalState < T extends Settings > {
212212 records : Array < Required < Plugin < Types < T > , T > > >
213+ reducers : Array < Required < Plugin < Types < T > , T > > [ Options . Reducer ] >
213214 initialState : { }
214215 state : { }
215216 log : Action [ ]
216217}
217218
218- class Lens < T extends Settings > {
219- private readonly state : LocalState < T > = {
220- records : [ ] ,
221- initialState : { } ,
222- state : { } ,
223- log : [ ]
224- }
219+ const normalizeRecords = < T extends Settings > (
220+ value : Plugin < Types < T > , T > [ ]
221+ ) : Required < Plugin < Types < T > , T > > [ ] => {
222+ const records : Required < Plugin < Types < T > , T > > [ ] = normalize ( value )
225223
226- // tslint:disable-next-line: function-name
227- public static normalizeRecords < T extends Settings > (
228- value : Plugin < Types < T > , T > [ ]
229- ) : Required < Plugin < Types < T > , T > > [ ] {
230- const records : Required < Plugin < Types < T > , T > > [ ] = normalize ( value )
224+ records . forEach ( record => {
225+ if ( ! isType ( record [ Options . Type ] ) ) {
226+ throw new Error ( 'Not valid [Options.Type]' )
227+ }
231228
232- records . forEach ( record => {
233- if ( ! isType ( record [ Options . Type ] ) ) {
234- throw new Error ( 'Not valid [Options.Type]' )
235- }
229+ if ( ! isBoolean ( record [ Options . Once ] ) ) {
230+ throw new Error (
231+ `Not valid [Options.Once] in the ${ String (
232+ record [ Options . Type ]
233+ ) } specification`
234+ )
235+ }
236236
237- if ( ! isBoolean ( record [ Options . Once ] ) ) {
238- throw new Error (
239- `Not valid [Options.Once ] in the ${ String (
240- record [ Options . Type ]
241- ) } specification`
242- )
243- }
237+ if ( ! every ( record [ Options . Dependencies ] , isType ) ) {
238+ throw new Error (
239+ `Not valid [Options.Dependencies ] in the ${ String (
240+ record [ Options . Type ]
241+ ) } specification`
242+ )
243+ }
244244
245- if ( ! every ( record [ Options . Dependencies ] , isType ) ) {
246- throw new Error (
247- `Not valid [Options.Dependencies ] in the ${ String (
248- record [ Options . Type ]
249- ) } specification`
250- )
251- }
245+ if ( ! every ( record [ Options . Conflicts ] , isType ) ) {
246+ throw new Error (
247+ `Not valid [Options.Conflicts ] in the ${ String (
248+ record [ Options . Type ]
249+ ) } specification`
250+ )
251+ }
252252
253- if ( ! every ( record [ Options . Conflicts ] , isType ) ) {
254- throw new Error (
255- `Not valid [Options.Conflicts ] in the ${ String (
256- record [ Options . Type ]
257- ) } specification`
258- )
259- }
253+ if ( ! isFunction ( record [ Options . Enabled ] ) ) {
254+ throw new Error (
255+ `Not valid [Options.Enabled ] in the ${ String (
256+ record [ Options . Type ]
257+ ) } specification`
258+ )
259+ }
260260
261- if ( ! isFunction ( record [ Options . Enabled ] ) ) {
262- throw new Error (
263- `Not valid [Options.Enabled ] in the ${ String (
264- record [ Options . Type ]
265- ) } specification`
266- )
267- }
261+ if ( ! isFunction ( record [ Options . Reducer ] ) ) {
262+ throw new Error (
263+ `Not valid [Options.Reducer ] in the ${ String (
264+ record [ Options . Type ]
265+ ) } specification`
266+ )
267+ }
268268
269- if ( ! isFunction ( record [ Options . Reducer ] ) ) {
270- throw new Error (
271- `Not valid [Options.Reducer] in the ${ String (
272- record [ Options . Type ]
273- ) } specification`
274- )
275- }
269+ if ( ! isPlainObject ( record [ Options . InitialState ] ) ) {
270+ throw new Error (
271+ `Not valid [Options.InitialState] in the ${ String (
272+ record [ Options . Type ]
273+ ) } specification`
274+ )
275+ }
276+ } )
276277
277- if ( ! isPlainObject ( record [ Options . InitialState ] ) ) {
278- throw new Error (
279- `Not valid [Options.InitialState] in the ${ String (
280- record [ Options . Type ]
281- ) } specification`
282- )
283- }
284- } )
278+ return records
279+ }
285280
286- return records
281+ class Lens < T extends Settings > {
282+ private readonly state : LocalState < T > = {
283+ records : [ ] ,
284+ reducers : [ ] ,
285+ initialState : { } ,
286+ state : { } ,
287+ log : [ ]
287288 }
288289
289- public dispatch ( action ?: Action , ...plugins : Plugin < Types < T > , T > [ ] ) {
290+ public readonly dispatch = (
291+ action ?: Action ,
292+ ...plugins : Plugin < Types < T > , T > [ ]
293+ ) => {
290294 if ( plugins . length !== 0 ) {
291- this . register ( Lens . normalizeRecords ( plugins ) )
295+ this . register ( normalizeRecords ( plugins ) )
292296 }
293297
294298 if ( ! isUndefined ( action ) ) {
@@ -304,7 +308,7 @@ class Lens<T extends Settings> {
304308 return this . interfaces ( )
305309 }
306310
307- public register ( records : Required < Plugin < Types < T > , T > > [ ] ) {
311+ public readonly register = ( records : Required < Plugin < Types < T > , T > > [ ] ) => {
308312 this . setRecords ( records )
309313
310314 this . state . initialState = Object . assign (
@@ -313,34 +317,40 @@ class Lens<T extends Settings> {
313317 )
314318 }
315319
320+ private readonly tests = (
321+ record : Required < Plugin < Types < T > , T > >
322+ ) : Array < ( ) => boolean > => [
323+ ( ) =>
324+ every ( record [ Options . Dependencies ] , type =>
325+ some ( this . state . log , action => action . type === type )
326+ ) ,
327+ ( ) => record [ Options . Enabled ] ( this . state . log , this . state . state ) ,
328+ ( ) =>
329+ record [ Options . Once ]
330+ ? ! some ( this . state . log , action => action . type === record [ Options . Type ] )
331+ : true ,
332+ ( ) =>
333+ ! some ( record [ Options . Conflicts ] , type =>
334+ some ( this . state . log , action => action . type === type )
335+ )
336+ ]
337+
316338 private setState ( ) {
317339 this . state . state = Object . assign (
318340 { } ,
319341 this . state . initialState ,
320- ...this . state . records . map ( record =>
321- record [ Options . Reducer ] ( this . state . log )
322- )
342+ ...this . state . reducers . map ( reducer => reducer ( this . state . log ) )
323343 )
324344 }
325345
326346 private disabled ( ) : Array < Required < Plugin < Types < T > , T > > > {
327- return this . state . records . filter ( record => {
328- const once = record [ Options . Once ]
329- ? ! some ( this . state . log , action => action . type === record [ Options . Type ] )
330- : true
331-
332- const enabled = record [ Options . Enabled ] ( this . state . log , this . state . state )
333-
334- const conflicts = ! some ( record [ Options . Conflicts ] , type =>
335- some ( this . state . log , action => action . type === type )
336- )
337-
338- const dependencies = every ( record [ Options . Dependencies ] , type =>
339- some ( this . state . log , action => action . type === type )
340- )
341-
342- return ! ( enabled && conflicts && dependencies && once )
343- } )
347+ return this . state . records . filter (
348+ record =>
349+ ! this . tests ( record ) . reduce (
350+ ( prev , curr ) => ( prev ? curr ( ) : false ) ,
351+ true as boolean
352+ )
353+ )
344354 }
345355
346356 // private enabled(): Array<Required<Plugin<Types<T>, T>>> {
@@ -363,7 +373,7 @@ class Lens<T extends Settings> {
363373 [ SYMBOL_STATE ] : this . state . state
364374 } ,
365375 ...this . state . records . map ( record =>
366- record [ Options . Interface ] ( this . dispatch . bind ( this ) , this . state . state )
376+ record [ Options . Interface ] ( this . dispatch , this . state . state )
367377 )
368378 )
369379
@@ -378,6 +388,10 @@ class Lens<T extends Settings> {
378388 private setRecords ( records : Required < Plugin < Types < T > , T > > [ ] ) {
379389 records . forEach ( record => {
380390 this . state . records . push ( record )
391+
392+ if ( this . state . reducers . indexOf ( record [ Options . Reducer ] ) === - 1 ) {
393+ this . state . reducers . push ( record [ Options . Reducer ] )
394+ }
381395 } )
382396 }
383397}
@@ -386,7 +400,7 @@ class Lens<T extends Settings> {
386400export const builder = < T extends Settings > (
387401 value : Plugin < Types < T > , T > [ ]
388402) : ( ( ) => Next < T > ) => {
389- const normalized = Lens . normalizeRecords ( value )
403+ const normalized = normalizeRecords ( value )
390404
391405 return ( ) => {
392406 const lens = new Lens < T > ( )
0 commit comments