Skip to content

Commit 2d12635

Browse files
committed
Add a specific compiler optimization for try(+..., fallback).
1 parent 34e47d0 commit 2d12635

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

defaultMethods.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,14 @@ const defaultMethods = {
370370
compile: (data, buildState) => {
371371
if (!Array.isArray(data) || !data.length) return false
372372
let res
373+
373374
try {
374-
res = buildState.compile`((context, above) => { try { return ${data[0]} } catch(err) { above = [null, context, above]; context = { type: err.type || err.message || err.toString() }; `
375+
// This is a very specific optimization to speed up the common case of trying to coerce a value to a number, and falling back to a different value.
376+
if ('+' in data[0] && data.length > 1) {
377+
res = buildState.compile`((context, above) => { try { const precoerceNumber = a => a; return Number.isNaN(prev = ${data[0]}) ? ${data[1]} : prev } catch(err) { above = [null, context, above]; context = { type: err.type || err.message || err.toString() }; `
378+
} else {
379+
res = buildState.compile`((context, above) => { try { return ${data[0]} } catch(err) { above = [null, context, above]; context = { type: err.type || err.message || err.toString() }; `
380+
}
375381
} catch (err) {
376382
// eslint-disable-next-line no-ex-assign
377383
if (Number.isNaN(err)) err = { type: 'NaN' }
@@ -1019,7 +1025,7 @@ defaultMethods['+'].compile = function (data, buildState) {
10191025
return `precoerceNumber(${data.map(i => numberCoercion(i, buildState)).join(' + ')})`
10201026
}
10211027
if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean') return `precoerceNumber(+${buildString(data, buildState)})`
1022-
return buildState.compile`(Array.isArray(prev = ${data}) ? prev.reduce((a,b) => (+a)+(+precoerceNumber(b)), 0) : +precoerceNumber(prev))`
1028+
return buildState.compile`(Array.isArray(prev = ${data}) ? prev.reduce((a,b) => (+a)+(+precoerceNumber(b)), 0) : precoerceNumber(+prev))`
10231029
}
10241030

10251031
// @ts-ignore Allow custom attribute
@@ -1044,7 +1050,7 @@ defaultMethods['-'].compile = function (data, buildState) {
10441050
return `${data.length === 1 ? '-' : ''}precoerceNumber(${data.map(i => numberCoercion(i, buildState)).join(' - ')})`
10451051
}
10461052
if (typeof data === 'string' || typeof data === 'number') return `(-${buildString(data, buildState)})`
1047-
return buildState.compile`(Array.isArray(prev = ${data}) ? prev.length === 1 ? -precoerceNumber(prev[0]) : assertSize(prev, 1).reduce((a,b) => (+precoerceNumber(a))-(+precoerceNumber(b))) : -precoerceNumber(prev))`
1053+
return buildState.compile`(Array.isArray(prev = ${data}) ? prev.length === 1 ? -precoerceNumber(prev[0]) : assertSize(prev, 1).reduce((a,b) => (+precoerceNumber(a))-(+precoerceNumber(b))) : -precoerceNumber(+prev))`
10481054
}
10491055
// @ts-ignore Allow custom attribute
10501056
defaultMethods['/'].compile = function (data, buildState) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-logic-engine",
3-
"version": "5.0.1",
3+
"version": "5.0.2",
44
"description": "Construct complex rules with JSON & process them.",
55
"main": "./dist/cjs/index.js",
66
"module": "./dist/esm/index.js",

suites/arithmetic/plus.extra.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
"result": 0,
66
"data": null
77
},
8+
{
9+
"description": "Plus val direct",
10+
"rule": { "+": { "val": "a" } },
11+
"data": { "a": "hello" },
12+
"error": { "type": "NaN" }
13+
},
814
{
915
"description": "Plus operator with unary array dynamic",
1016
"rule": { "+": { "preserve": [7] } },
@@ -17,4 +23,4 @@
1723
"result": 15,
1824
"data": null
1925
}
20-
]
26+
]

0 commit comments

Comments
 (0)