@@ -9,6 +9,7 @@ import { buildAsync } from './compiler.js'
99import omitUndefined from './utilities/omitUndefined.js'
1010import { optimize } from './async_optimizer.js'
1111import { applyPatches } from './compatibility.js'
12+ import { coerceArray } from './utilities/coerceArray.js'
1213
1314/**
1415 * An engine capable of running asynchronous JSON Logic.
@@ -75,16 +76,15 @@ class AsyncLogicEngine {
7576 if ( ! this . methods [ func ] ) throw new Error ( `Method '${ func } ' was not found in the Logic Engine.` )
7677
7778 if ( typeof this . methods [ func ] === 'function' ) {
78- const input = await this . run ( data , context , { above } )
79- const result = await this . methods [ func ] ( input , context , above , this )
79+ const input = ( ! data || typeof data !== 'object' ) ? [ data ] : await this . run ( data , context , { above } )
80+ const result = await this . methods [ func ] ( coerceArray ( input ) , context , above , this )
8081 return Array . isArray ( result ) ? Promise . all ( result ) : result
8182 }
8283
8384 if ( typeof this . methods [ func ] === 'object' ) {
8485 const { asyncMethod, method, traverse } = this . methods [ func ]
8586 const shouldTraverse = typeof traverse === 'undefined' ? true : traverse
86- const parsedData = shouldTraverse ? await this . run ( data , context , { above } ) : data
87-
87+ const parsedData = shouldTraverse ? ( ( ! data || typeof data !== 'object' ) ? [ data ] : coerceArray ( await this . run ( data , context , { above } ) ) ) : data
8888 const result = await ( asyncMethod || method ) ( parsedData , context , above , this )
8989 return Array . isArray ( result ) ? Promise . all ( result ) : result
9090 }
@@ -96,12 +96,12 @@ class AsyncLogicEngine {
9696 *
9797 * @param {String } name The name of the method being added.
9898 * @param {((args: any, context: any, above: any[], engine: AsyncLogicEngine) => any) | { traverse?: Boolean, method?: (args: any, context: any, above: any[], engine: AsyncLogicEngine) => any, asyncMethod?: (args: any, context: any, above: any[], engine: AsyncLogicEngine) => Promise<any>, deterministic?: Function | Boolean } } method
99- * @param {{ deterministic?: Boolean, async?: Boolean, sync?: Boolean } } annotations This is used by the compiler to help determine if it can optimize the function being generated.
99+ * @param {{ deterministic?: Boolean, async?: Boolean, sync?: Boolean, optimizeUnary?: boolean } } annotations This is used by the compiler to help determine if it can optimize the function being generated.
100100 */
101101 addMethod (
102102 name ,
103103 method ,
104- { deterministic, async, sync } = { }
104+ { deterministic, async, sync, optimizeUnary } = { }
105105 ) {
106106 if ( typeof async === 'undefined' && typeof sync === 'undefined' ) sync = false
107107 if ( typeof sync !== 'undefined' ) async = ! sync
@@ -112,7 +112,7 @@ class AsyncLogicEngine {
112112 else method = { method, traverse : true }
113113 } else method = { ...method }
114114
115- Object . assign ( method , omitUndefined ( { deterministic } ) )
115+ Object . assign ( method , omitUndefined ( { deterministic, optimizeUnary } ) )
116116 // @ts -ignore
117117 this . fallback . addMethod ( name , method , { deterministic } )
118118 this . methods [ name ] = declareSync ( method , sync )
@@ -188,6 +188,8 @@ class AsyncLogicEngine {
188188 async build ( logic , options = { } ) {
189189 const { above = [ ] , top = true } = options
190190 this . fallback . truthy = this . truthy
191+ // @ts -ignore
192+ this . fallback . allowFunctions = this . allowFunctions
191193 if ( top ) {
192194 const constructedFunction = await buildAsync ( logic , { engine : this , above, async : true , state : { } } )
193195
0 commit comments