@@ -212,6 +212,7 @@ const defaultMethods = {
212212 // Why "executeInLoop"? Because if it needs to execute to get an array, I do not want to execute the arguments,
213213 // Both for performance and safety reasons.
214214 '??' : {
215+ [ Sync ] : ( data , buildState ) => isSyncDeep ( data , buildState . engine , buildState ) ,
215216 method : ( arr , _1 , _2 , engine ) => {
216217 // See "executeInLoop" above
217218 const executeInLoop = Array . isArray ( arr )
@@ -249,6 +250,7 @@ const defaultMethods = {
249250 traverse : false
250251 } ,
251252 or : {
253+ [ Sync ] : ( data , buildState ) => isSyncDeep ( data , buildState . engine , buildState ) ,
252254 method : ( arr , _1 , _2 , engine ) => {
253255 // See "executeInLoop" above
254256 const executeInLoop = Array . isArray ( arr )
@@ -284,6 +286,7 @@ const defaultMethods = {
284286 traverse : false
285287 } ,
286288 and : {
289+ [ Sync ] : ( data , buildState ) => isSyncDeep ( data , buildState . engine , buildState ) ,
287290 method : ( arr , _1 , _2 , engine ) => {
288291 // See "executeInLoop" above
289292 const executeInLoop = Array . isArray ( arr )
@@ -419,6 +422,7 @@ const defaultMethods = {
419422 some : createArrayIterativeMethod ( 'some' , true ) ,
420423 all : createArrayIterativeMethod ( 'every' , true ) ,
421424 none : {
425+ [ Sync ] : ( data , buildState ) => isSyncDeep ( data , buildState . engine , buildState ) ,
422426 traverse : false ,
423427 // todo: add async build & build
424428 method : ( val , context , above , engine ) => {
@@ -439,7 +443,7 @@ const defaultMethods = {
439443 } ,
440444 merge : ( arrays ) => ( Array . isArray ( arrays ) ? [ ] . concat ( ...arrays ) : [ arrays ] ) ,
441445 every : createArrayIterativeMethod ( 'every' ) ,
442- filter : createArrayIterativeMethod ( 'filter' ) ,
446+ filter : createArrayIterativeMethod ( 'filter' , true ) ,
443447 reduce : {
444448 deterministic : ( data , buildState ) => {
445449 return (
@@ -548,11 +552,27 @@ const defaultMethods = {
548552 } ,
549553 '!' : ( value , _1 , _2 , engine ) => Array . isArray ( value ) ? ! engine . truthy ( value [ 0 ] ) : ! engine . truthy ( value ) ,
550554 '!!' : ( value , _1 , _2 , engine ) => Boolean ( Array . isArray ( value ) ? engine . truthy ( value [ 0 ] ) : engine . truthy ( value ) ) ,
551- cat : ( arr ) => {
552- if ( typeof arr === 'string' ) return arr
553- let res = ''
554- for ( let i = 0 ; i < arr . length ; i ++ ) res += arr [ i ]
555- return res
555+ cat : {
556+ [ OriginalImpl ] : true ,
557+ [ Sync ] : true ,
558+ method : ( arr ) => {
559+ if ( typeof arr === 'string' ) return arr
560+ if ( ! Array . isArray ( arr ) ) return arr . toString ( )
561+ let res = ''
562+ for ( let i = 0 ; i < arr . length ; i ++ ) res += arr [ i ] . toString ( )
563+ return res
564+ } ,
565+ deterministic : true ,
566+ traverse : true ,
567+ optimizeUnary : true ,
568+ compile : ( data , buildState ) => {
569+ if ( typeof data === 'string' ) return JSON . stringify ( data )
570+ if ( typeof data === 'number' ) return '"' + JSON . stringify ( data ) + '"'
571+ if ( ! Array . isArray ( data ) ) return false
572+ let res = buildState . compile `''`
573+ for ( let i = 0 ; i < data . length ; i ++ ) res = buildState . compile `${ res } + ${ data [ i ] } `
574+ return buildState . compile `(${ res } )`
575+ }
556576 } ,
557577 keys : ( [ obj ] ) => typeof obj === 'object' ? Object . keys ( obj ) : [ ] ,
558578 pipe : {
@@ -673,8 +693,8 @@ function createArrayIterativeMethod (name, useTruthy = false) {
673693 ( await engine . run ( selector , context , {
674694 above
675695 } ) ) || [ ]
676- return asyncIterators [ name ] ( selector , ( i , index ) => {
677- const result = engine . run ( mapper , i , {
696+ return asyncIterators [ name ] ( selector , async ( i , index ) => {
697+ const result = await engine . run ( mapper , i , {
678698 above : [ { iterator : selector , index } , context , above ]
679699 } )
680700 return useTruthy ? engine . truthy ( result ) : result
@@ -694,15 +714,16 @@ function createArrayIterativeMethod (name, useTruthy = false) {
694714
695715 const method = build ( mapper , mapState )
696716 const aboveArray = method . aboveDetected ? buildState . compile `[{ iterator: z, index: x }, context, above]` : buildState . compile `null`
717+ const useTruthyMethod = useTruthy ? buildState . compile `engine.truthy` : buildState . compile ``
697718
698719 if ( async ) {
699720 if ( ! isSync ( method ) ) {
700721 buildState . asyncDetected = true
701- return buildState . compile `await asyncIterators[${ name } ](${ selector } || [], async (i, x, z) => ${ method } (i, x, ${ aboveArray } ))`
722+ return buildState . compile `await asyncIterators[${ name } ](${ selector } || [], async (i, x, z) => ${ useTruthyMethod } ( ${ method } (i, x, ${ aboveArray } ) ))`
702723 }
703724 }
704725
705- return buildState . compile `(${ selector } || [])[${ name } ]((i, x, z) => ${ method } (i, x, ${ aboveArray } ))`
726+ return buildState . compile `(${ selector } || [])[${ name } ]((i, x, z) => ${ useTruthyMethod } ( ${ method } (i, x, ${ aboveArray } ) ))`
706727 } ,
707728 traverse : false
708729 }
0 commit comments