@@ -7,7 +7,7 @@ import declareSync from './utilities/declareSync.js'
77import { build , buildString } from './compiler.js'
88import chainingSupported from './utilities/chainingSupported.js'
99import legacyMethods from './legacy.js'
10- import { precoerceNumber } from './utilities/downgrade.js'
10+ import { precoerceNumber , assertNotType } from './utilities/downgrade.js'
1111
1212const INVALID_ARGUMENTS = { type : 'Invalid Arguments' }
1313
@@ -32,7 +32,7 @@ function isDeterministic (method, engine, buildState) {
3232 return typeof engine . methods [ func ] . deterministic === 'function'
3333 ? engine . methods [ func ] . deterministic ( lower , buildState )
3434 : engine . methods [ func ] . deterministic &&
35- isDeterministic ( lower , engine , buildState )
35+ isDeterministic ( lower , engine , buildState )
3636 }
3737 return true
3838}
@@ -315,9 +315,9 @@ const defaultMethods = {
315315 if ( Array . isArray ( data ) && data . length ) {
316316 return `(${ data . map ( ( i , x ) => {
317317 const built = buildString ( i , buildState )
318- if ( Array . isArray ( i ) || ! i || typeof i !== 'object' || x === data . length - 1 ) return built
319- return '(' + built + ')'
320- } ) . join ( ' ?? ' ) } )`
318+ if ( Array . isArray ( i ) || ! i || typeof i !== 'object' || x === data . length - 1 ) return built
319+ return '(' + built + ')'
320+ } ) . join ( ' ?? ' ) } )`
321321 }
322322 return `(${ buildString ( data , buildState ) } ).reduce((a,b) => (a) ?? b, null)`
323323 } ,
@@ -653,40 +653,37 @@ const defaultMethods = {
653653 }
654654 mapper = build ( mapper , mapState )
655655 const aboveArray = mapper . aboveDetected ? '[null, context, above]' : 'null'
656-
656+ const verifyAccumulator = buildState . engine . options . enableObjectAccumulators ? '' : 'assertNotType'
657657 buildState . methods . push ( mapper )
658+
658659 if ( async ) {
659660 if ( ! isSync ( mapper ) || selector . includes ( 'await' ) ) {
660661 buildState . asyncDetected = true
661662 if ( typeof defaultValue !== 'undefined' ) {
662- return `await asyncIterators.reduce(${ selector } || [], (a,b) => methods[${
663- buildState . methods . length - 1
664- } ]({ accumulator: a, current: b }, ${ aboveArray } ), ${ defaultValue } )`
663+ return `await asyncIterators.reduce(${ selector } || [], (a,b) => methods[${ buildState . methods . length - 1 } ]({ accumulator: a, current: b }, ${ aboveArray } ), ${ defaultValue } , ${ buildState . engine . options . enableObjectAccumulators } )`
665664 }
666- return `await asyncIterators.reduce(${ selector } || [], (a,b) => methods[${
667- buildState . methods . length - 1
668- } ]({ accumulator: a, current: b }, ${ aboveArray } ))`
665+ return `await asyncIterators.reduce(${ selector } || [], (a,b) => methods[${ buildState . methods . length - 1 } ]({ accumulator: a, current: b }, ${ aboveArray } ), undefined, ${ buildState . engine . options . enableObjectAccumulators } )`
669666 }
670667 }
668+
671669 if ( typeof defaultValue !== 'undefined' ) {
672- return `(${ selector } || []).reduce((a,b) => methods[${
673- buildState . methods . length - 1
674- } ]({ accumulator: a, current: b }, ${ aboveArray } ), ${ defaultValue } )`
670+ return `(${ selector } || []).reduce((a,b) => ${ verifyAccumulator } (methods[${ buildState . methods . length - 1 } ]({ accumulator: a, current: b }, ${ aboveArray } )), ${ verifyAccumulator } (${ defaultValue } ))`
675671 }
676- return `(${ selector } || []).reduce((a,b) => methods[${
677- buildState . methods . length - 1
678- } ]({ accumulator: a, current: b }, ${ aboveArray } ))`
672+ return `(${ selector } || []).reduce((a,b) => ${ verifyAccumulator } (methods[${ buildState . methods . length - 1 } ]({ accumulator: a, current: b }, ${ aboveArray } )))`
679673 } ,
680674 method : ( input , context , above , engine ) => {
681675 if ( ! Array . isArray ( input ) ) throw INVALID_ARGUMENTS
682676 let [ selector , mapper , defaultValue ] = input
683- defaultValue = runOptimizedOrFallback ( defaultValue , engine , context , above )
677+
678+ const verifyAccumulator = engine . options . enableObjectAccumulators ? a => a : assertNotType
679+
680+ defaultValue = verifyAccumulator ( runOptimizedOrFallback ( defaultValue , engine , context , above ) )
684681 selector = runOptimizedOrFallback ( selector , engine , context , above ) || [ ]
685- let func = ( accumulator , current ) => engine . run ( mapper , { accumulator, current } , { above : [ selector , context , above ] } )
682+ let func = ( accumulator , current ) => verifyAccumulator ( engine . run ( mapper , { accumulator, current } , { above : [ selector , context , above ] } ) , 'object' )
686683
687684 if ( engine . optimizedMap . has ( mapper ) && typeof engine . optimizedMap . get ( mapper ) === 'function' ) {
688685 const optimized = engine . optimizedMap . get ( mapper )
689- func = ( accumulator , current ) => optimized ( { accumulator, current } , [ selector , context , above ] )
686+ func = ( accumulator , current ) => verifyAccumulator ( optimized ( { accumulator, current } , [ selector , context , above ] ) )
690687 }
691688
692689 if ( typeof defaultValue === 'undefined' ) return selector . reduce ( func )
@@ -697,13 +694,10 @@ const defaultMethods = {
697694 asyncMethod : async ( input , context , above , engine ) => {
698695 if ( ! Array . isArray ( input ) ) throw INVALID_ARGUMENTS
699696 let [ selector , mapper , defaultValue ] = input
700- defaultValue = await engine . run ( defaultValue , context , {
701- above
702- } )
703- selector =
704- ( await engine . run ( selector , context , {
705- above
706- } ) ) || [ ]
697+ const verifyAccumulator = engine . options . enableObjectAccumulators ? a => a : assertNotType
698+
699+ defaultValue = verifyAccumulator ( await engine . run ( defaultValue , context , { above } ) )
700+ selector = ( await engine . run ( selector , context , { above } ) ) || [ ]
707701 return asyncIterators . reduce (
708702 selector ,
709703 ( accumulator , current ) => {
@@ -718,7 +712,8 @@ const defaultMethods = {
718712 }
719713 )
720714 } ,
721- defaultValue
715+ defaultValue ,
716+ engine . enableObjectAccumulators
722717 )
723718 } ,
724719 lazy : true
@@ -827,7 +822,8 @@ const defaultMethods = {
827822 } )
828823 return accumulator
829824 } ,
830- { }
825+ { } ,
826+ true
831827 )
832828 return result
833829 }
@@ -1058,11 +1054,11 @@ defaultMethods['/'].compile = function (data, buildState) {
10581054 if ( data . length === 0 ) throw INVALID_ARGUMENTS
10591055 if ( data . length === 1 ) data = [ 1 , data [ 0 ] ]
10601056 return `precoerceNumber(${ data . map ( ( i , x ) => {
1061- let res = numberCoercion ( i , buildState )
1062- if ( x && res === '+0' ) precoerceNumber ( NaN )
1063- if ( x ) res = `precoerceNumber(${ res } || NaN)`
1064- return res
1065- } ) . join ( ' / ' ) } )`
1057+ let res = numberCoercion ( i , buildState )
1058+ if ( x && res === '+0' ) precoerceNumber ( NaN )
1059+ if ( x ) res = `precoerceNumber(${ res } || NaN)`
1060+ return res
1061+ } ) . join ( ' / ' ) } )`
10661062 }
10671063 return `assertSize(prev = ${ buildString ( data , buildState ) } , 1) && prev.length === 1 ? 1 / precoerceNumber(prev[0] || NaN) : prev.reduce((a,b) => (+precoerceNumber(a))/(+precoerceNumber(b || NaN)))`
10681064}
0 commit comments