@@ -7,7 +7,7 @@ import declareSync from './utilities/declareSync.js'
7
7
import { build , buildString } from './compiler.js'
8
8
import chainingSupported from './utilities/chainingSupported.js'
9
9
import InvalidControlInput from './errors/InvalidControlInput.js'
10
- import { splitPath } from './utilities/splitPath.js'
10
+ import { splitPathMemoized } from './utilities/splitPath.js'
11
11
12
12
function isDeterministic ( method , engine , buildState ) {
13
13
if ( Array . isArray ( method ) ) {
@@ -34,17 +34,36 @@ function isDeterministic (method, engine, buildState) {
34
34
}
35
35
36
36
const defaultMethods = {
37
- '+' : ( data ) => [ ] . concat ( data ) . reduce ( ( a , b ) => + a + + b , 0 ) ,
38
- '*' : ( data ) => data . reduce ( ( a , b ) => + a * + b ) ,
39
- '/' : ( data ) => data . reduce ( ( a , b ) => + a / + b ) ,
40
-
41
- '-' : ( data ) =>
42
- // @ts -ignore Type checking is incorrect on the following line.
43
- ( ( a ) => ( a . length === 1 ? ( a [ 0 ] = - a [ 0 ] ) : a ) & 0 || a ) (
44
- [ ] . concat ( data )
45
- // @ts -ignore Type checking is incorrect on the following line.
46
- ) . reduce ( ( a , b ) => + a - + b ) ,
47
- '%' : ( data ) => data . reduce ( ( a , b ) => + a % + b ) ,
37
+ '+' : ( data ) => {
38
+ if ( typeof data === 'string' ) return + data
39
+ if ( typeof data === 'number' ) return + data
40
+ let res = 0
41
+ for ( let i = 0 ; i < data . length ; i ++ ) res += + data [ i ]
42
+ return res
43
+ } ,
44
+ '*' : ( data ) => {
45
+ let res = 1
46
+ for ( let i = 0 ; i < data . length ; i ++ ) res *= + data [ i ]
47
+ return res
48
+ } ,
49
+ '/' : ( data ) => {
50
+ let res = data [ 0 ]
51
+ for ( let i = 1 ; i < data . length ; i ++ ) res /= + data [ i ]
52
+ return res
53
+ } ,
54
+ '-' : ( data ) => {
55
+ if ( typeof data === 'string' ) return - data
56
+ if ( typeof data === 'number' ) return - data
57
+ if ( data . length === 1 ) return - data [ 0 ]
58
+ let res = data [ 0 ]
59
+ for ( let i = 1 ; i < data . length ; i ++ ) res -= + data [ i ]
60
+ return res
61
+ } ,
62
+ '%' : ( data ) => {
63
+ let res = data [ 0 ]
64
+ for ( let i = 1 ; i < data . length ; i ++ ) res %= + data [ i ]
65
+ return res
66
+ } ,
48
67
max : ( data ) => Math . max ( ...data ) ,
49
68
min : ( data ) => Math . min ( ...data ) ,
50
69
in : ( [ item , array ] ) => ( array || [ ] ) . includes ( item ) ,
@@ -145,8 +164,18 @@ const defaultMethods = {
145
164
'!=' : ( [ a , b ] ) => a != b ,
146
165
'!==' : ( [ a , b ] ) => a !== b ,
147
166
xor : ( [ a , b ] ) => a ^ b ,
148
- or : ( arr ) => arr . reduce ( ( a , b ) => a || b , false ) ,
149
- and : ( arr ) => arr . reduce ( ( a , b ) => a && b ) ,
167
+ or : ( arr ) => {
168
+ for ( let i = 0 ; i < arr . length ; i ++ ) {
169
+ if ( arr [ i ] ) return arr [ i ]
170
+ }
171
+ return arr [ arr . length - 1 ]
172
+ } ,
173
+ and : ( arr ) => {
174
+ for ( let i = 0 ; i < arr . length ; i ++ ) {
175
+ if ( ! arr [ i ] ) return arr [ i ]
176
+ }
177
+ return arr [ arr . length - 1 ]
178
+ } ,
150
179
substr : ( [ string , from , end ] ) => {
151
180
if ( end < 0 ) {
152
181
const result = string . substr ( from )
@@ -163,7 +192,7 @@ const defaultMethods = {
163
192
method : ( [ data , key , defaultValue ] , context , above , engine ) => {
164
193
const notFound = defaultValue === undefined ? null : defaultValue
165
194
166
- const subProps = splitPath ( String ( key ) )
195
+ const subProps = splitPathMemoized ( String ( key ) )
167
196
for ( let i = 0 ; i < subProps . length ; i ++ ) {
168
197
if ( data === null || data === undefined ) {
169
198
return notFound
@@ -205,7 +234,7 @@ const defaultMethods = {
205
234
}
206
235
return null
207
236
}
208
- const subProps = splitPath ( String ( key ) )
237
+ const subProps = splitPathMemoized ( String ( key ) )
209
238
for ( let i = 0 ; i < subProps . length ; i ++ ) {
210
239
if ( context === null || context === undefined ) {
211
240
return notFound
@@ -815,7 +844,7 @@ defaultMethods.get.compile = function (data, buildState) {
815
844
if ( key && typeof key === 'object' ) return false
816
845
817
846
key = key . toString ( )
818
- const pieces = splitPath ( key )
847
+ const pieces = splitPathMemoized ( key )
819
848
if ( ! chainingSupported ) {
820
849
return `(((a,b) => (typeof a === 'undefined' || a === null) ? b : a)(${ pieces . reduce (
821
850
( text , i ) => {
@@ -864,7 +893,7 @@ defaultMethods.var.compile = function (data, buildState) {
864
893
buildState . useContext = true
865
894
return false
866
895
}
867
- const pieces = splitPath ( key )
896
+ const pieces = splitPathMemoized ( key )
868
897
const [ top ] = pieces
869
898
buildState . varTop . add ( top )
870
899
0 commit comments