33
44import  { 
55  isSync , 
6-   // Override is required for the compiler to operate as intended. 
7-   Override , 
8-   Sync 
6+   Sync , 
7+   Compiled 
98}  from  './constants.js' 
109import  declareSync  from  './utilities/declareSync.js' 
1110
1211// asyncIterators is required for the compiler to operate as intended. 
1312import  asyncIterators  from  './async_iterators.js' 
1413
14+ /** 
15+  * Provides a simple way to compile logic into a function that can be run. 
16+  * @param  {string[] } strings 
17+  * @param   {...any } items 
18+  * @returns  {{ [Compiled]: string } } 
19+  */ 
20+ function  compileTemplate  ( strings ,  ...items )  { 
21+   let  res  =  '' 
22+   for  ( let  i  =  0 ;  i  <  strings . length ;  i ++ )  { 
23+     res  +=  strings [ i ] 
24+     if  ( i  <  items . length )  { 
25+       if  ( typeof  items [ i ]  ===  'function' )  { 
26+         this . methods . push ( items [ i ] ) 
27+         res  +=  'methods['  +  ( this . methods . length  -  1 )  +  ']' 
28+       }  else  if  ( items [ i ]  &&  typeof  items [ i ] [ Compiled ]  !==  'undefined' )  res  +=  items [ i ] [ Compiled ] 
29+       else  res  +=  buildString ( items [ i ] ,  this ) 
30+     } 
31+   } 
32+   return  {  [ Compiled ] : res  } 
33+ } 
34+ 
1535/** 
1636 * @typedef  BuildState 
1737 * Used to keep track of the compilation. 
1838 * @property  {* } [engine] 
1939 * @property  {Object } [notTraversed] 
20-  * @property  {Object } [functions] 
2140 * @property  {Object } [methods] 
2241 * @property  {Object } [state] 
2342 * @property  {Array } [processing] 
2443 * @property  {* } [async] 
2544 * @property  {Array } [above] 
2645 * @property  {Boolean } [asyncDetected] 
2746 * @property  {* } [values] 
28-  * @property  {Boolean } [useContext] 
2947 * @property  {Boolean } [avoidInlineAsync] 
3048 * @property  {string } [extraArguments] 
31-  * 
49+  *  @property  { (strings: string[], ...items: any[]) => { compiled: string } } [compile] A function that can be used to compile a template.  
3250 */ 
3351
3452/** 
@@ -117,11 +135,7 @@ function isDeepSync (method, engine) {
117135function  buildString  ( method ,  buildState  =  { } )  { 
118136  const  { 
119137    notTraversed =  [ ] , 
120-     functions =  { } , 
121-     // methods = [], 
122-     // state, 
123138    async, 
124-     // above = [], 
125139    processing =  [ ] , 
126140    values =  [ ] , 
127141    engine
@@ -150,7 +164,6 @@ function buildString (method, buildState = {}) {
150164  } 
151165
152166  const  func  =  method  &&  Object . keys ( method ) [ 0 ] 
153-   buildState . useContext  =  buildState . useContext  ||  ( engine . methods [ func ]  ||  { } ) . useContext 
154167
155168  if  ( method  &&  typeof  method  ===  'object' )  { 
156169    if  ( ! func )  return  pushValue ( method ) 
@@ -159,7 +172,6 @@ function buildString (method, buildState = {}) {
159172      if  ( engine . isData ( method ,  func ) )  return  pushValue ( method ,  true ) 
160173      throw  new  Error ( `Method '${ func }  ' was not found in the Logic Engine.` ) 
161174    } 
162-     functions [ func ]  =  functions [ func ]  ||  2 
163175
164176    if  ( 
165177      ! buildState . engine . disableInline  && 
@@ -175,31 +187,25 @@ function buildString (method, buildState = {}) {
175187    } 
176188
177189    if  ( engine . methods [ func ]  &&  engine . methods [ func ] . compile )  { 
178-       const  str  =  engine . methods [ func ] . compile ( method [ func ] ,  buildState ) 
190+       let  str  =  engine . methods [ func ] . compile ( method [ func ] ,  buildState ) 
191+       if  ( str [ Compiled ] )  str  =  str [ Compiled ] 
179192
180193      if  ( ( str  ||  '' ) . startsWith ( 'await' ) )  buildState . asyncDetected  =  true 
181194
182195      if  ( str  !==  false )  return  str 
183196    } 
184197
185198    if  ( typeof  engine . methods [ func ]  ===  'function' )  { 
186-       functions [ func ]  =  1 
187199      asyncDetected  =  ! isSync ( engine . methods [ func ] ) 
188- 
189-       return  makeAsync ( `gen["${ func }  "](`  +  buildString ( method [ func ] ,  buildState )  +  ')' ) 
200+       return  makeAsync ( `engine.methods["${ func }  "](`  +  buildString ( method [ func ] ,  buildState )  +  ', context, above, engine)' ) 
190201    }  else  { 
191202      if  ( engine . methods [ func ]  &&  ( typeof  engine . methods [ func ] . traverse  ===  'undefined'  ? true  : engine . methods [ func ] . traverse ) )  { 
192-         functions [ func ]  =  1 
193203        asyncDetected  =  Boolean ( async  &&  engine . methods [ func ]  &&  engine . methods [ func ] . asyncMethod ) 
194- 
195-         return  makeAsync ( `gen["${ func }  "](`  +  buildString ( method [ func ] ,  buildState )  +  ')' ) 
204+         return  makeAsync ( `engine.methods["${ func }  "]${ asyncDetected  ? '.asyncMethod'  : '.method' }  (`  +  buildString ( method [ func ] ,  buildState )  +  ', context, above, engine)' ) 
196205      }  else  { 
197206        asyncDetected  =  Boolean ( async  &&  engine . methods [ func ]  &&  engine . methods [ func ] . asyncMethod ) 
198- 
199-         functions [ func ]  =  1 
200207        notTraversed . push ( method [ func ] ) 
201- 
202-         return  makeAsync ( `gen["${ func }  "](`  +  `notTraversed[${ notTraversed . length  -  1 }  ]`  +  ')' ) 
208+         return  makeAsync ( `engine.methods["${ func }  "]${ asyncDetected  ? '.asyncMethod'  : '.method' }  (`  +  `notTraversed[${ notTraversed . length  -  1 }  ]`  +  ', context, above, engine)' ) 
203209      } 
204210    } 
205211  } 
@@ -218,14 +224,13 @@ function build (method, buildState = {}) {
218224    Object . assign ( 
219225      { 
220226        notTraversed : [ ] , 
221-         functions : { } , 
222227        methods : [ ] , 
223228        state : { } , 
224229        processing : [ ] , 
225230        async : buildState . engine . async , 
226-         above : [ ] , 
227231        asyncDetected : false , 
228-         values : [ ] 
232+         values : [ ] , 
233+         compile : compileTemplate 
229234      } , 
230235      buildState 
231236    ) 
@@ -246,20 +251,19 @@ async function buildAsync (method, buildState = {}) {
246251    Object . assign ( 
247252      { 
248253        notTraversed : [ ] , 
249-         functions : { } , 
250254        methods : [ ] , 
251255        state : { } , 
252256        processing : [ ] , 
253257        async : buildState . engine . async , 
254-         above : [ ] , 
255258        asyncDetected : false , 
256-         values : [ ] 
259+         values : [ ] , 
260+         compile : compileTemplate 
257261      } , 
258262      buildState 
259263    ) 
260264  ) 
261265  const  str  =  buildString ( method ,  buildState ) 
262-   buildState . processing  =  await  Promise . all ( buildState . processing ) 
266+   buildState . processing  =  await  Promise . all ( buildState . processing   ||   [ ] ) 
263267  return  processBuiltString ( method ,  str ,  buildState ) 
264268} 
265269
@@ -271,58 +275,26 @@ async function buildAsync (method, buildState = {}) {
271275 * @returns  
272276 */ 
273277function  processBuiltString  ( method ,  str ,  buildState )  { 
274-   const  gen  =  { } 
275278  const  { 
276-     functions, 
277-     state, 
278-     async, 
279279    engine, 
280-     above, 
281280    methods, 
282281    notTraversed, 
283-     processing, 
282+     processing  =   [ ] , 
284283    values
285284  }  =  buildState 
286-   processing . forEach ( ( item ,  x )  =>  { 
287-     str  =  str . replace ( `__%%%${ x }  %%%__` ,  item ) 
288-   } ) 
289-   Object . keys ( functions ) . forEach ( ( key )  =>  { 
290-     if  ( functions [ key ]  ===  2 )  return 
291285
292-      if   ( ! engine . methods [ key ] )   throw   new   Error ( `Method ' ${ key } ' was not found in the Logic Engine.` ) 
286+   const   above   =   [ ] 
293287
294-     if  ( typeof  engine . methods [ key ]  ===  'function' )  { 
295-       const  method  =  engine . methods [ key ] 
296-       gen [ key ]  =  ( input )  =>  method ( input ,  state ,  above ,  engine ) 
297-     }  else  { 
298-       if  ( async  &&  engine . methods [ key ] . asyncMethod )  { 
299-         buildState . asyncDetected  =  true 
300-         const  method  =  engine . methods [ key ] . asyncMethod 
301-         gen [ key ]  =  ( input )  =>  method ( input ,  state ,  above ,  engine ) 
302-       }  else  { 
303-         const  method  =  engine . methods [ key ] . method 
304-         gen [ key ]  =  ( input )  =>  method ( input ,  state ,  above ,  engine ) 
305-       } 
306-     } 
288+   processing . forEach ( ( item ,  x )  =>  { 
289+     str  =  str . replace ( `__%%%${ x }  %%%__` ,  item ) 
307290  } ) 
308291
309-   if  ( ! Object . keys ( functions ) . length )  return  method 
310- 
311-   let  copyStateCall  =  'state[Override] = context;' 
312-   // console.log(buildState.useContext) 
313- 
314-   if  ( ! buildState . useContext )  { 
315-     copyStateCall  =  '' 
316-     str  =  str . replace ( / s t a t e \[ O v e r r i d e \] / g,  'context' ) 
317-   } 
318- 
319-   methods . truthy  =  engine . truthy 
320-   const  final  =  `(state, values, methods, gen, notTraversed, Override, asyncIterators) => ${ buildState . asyncDetected  ? 'async'  : '' }   (context ${ buildState . extraArguments  ? ','  +  buildState . extraArguments  : '' }  ) => { ${ copyStateCall }   const result = ${ str }  ; return result }` 
292+   const  final  =  `(values, methods, notTraversed, asyncIterators, engine, above) => ${ buildState . asyncDetected  ? 'async'  : '' }   (context ${ buildState . extraArguments  ? ','  +  buildState . extraArguments  : '' }  ) => { const result = ${ str }  ; return result }` 
321293
322294  // console.log(str) 
323295  // console.log(final) 
324296  // eslint-disable-next-line no-eval 
325-   return  declareSync ( ( typeof  globalThis  !==  'undefined'  ? globalThis  : global ) . eval ( final ) ( state ,   values ,  methods ,  gen ,   notTraversed ,   Override ,   asyncIterators ) ,  ! buildState . asyncDetected ) 
297+   return  declareSync ( ( typeof  globalThis  !==  'undefined'  ? globalThis  : global ) . eval ( final ) ( values ,  methods ,  notTraversed ,   asyncIterators ,   engine ,   above ) ,  ! buildState . asyncDetected ) 
326298} 
327299
328300export  {  build  } 
0 commit comments