Skip to content

Commit db57dec

Browse files
Merge pull request #39 from json-logic/proposal/val
`val` Proposal Implementation
2 parents 2217e6d + e52f768 commit db57dec

21 files changed

+1313
-308
lines changed

asyncLogic.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import defaultMethods from './defaultMethods.js'
55
import LogicEngine from './logic.js'
6-
import { isSync } from './constants.js'
6+
import { isSync, OriginalImpl } from './constants.js'
77
import declareSync from './utilities/declareSync.js'
88
import { buildAsync } from './compiler.js'
99
import omitUndefined from './utilities/omitUndefined.js'
@@ -75,6 +75,13 @@ class AsyncLogicEngine {
7575
if (this.isData(logic, func)) return logic
7676
if (!this.methods[func]) throw new Error(`Method '${func}' was not found in the Logic Engine.`)
7777

78+
// A small but useful micro-optimization for some of the most common functions.
79+
// Later on, I could define something to shut this off if var / val are redefined.
80+
if ((func === 'var' || func === 'val') && this.methods[func][OriginalImpl]) {
81+
const input = (!data || typeof data !== 'object') ? data : this.fallback.run(data, context, { above })
82+
return this.methods[func].method(input, context, above, this)
83+
}
84+
7885
if (typeof this.methods[func] === 'function') {
7986
const input = (!data || typeof data !== 'object') ? [data] : await this.run(data, context, { above })
8087
const result = await this.methods[func](coerceArray(input), context, above, this)
@@ -210,5 +217,5 @@ class AsyncLogicEngine {
210217
return logic
211218
}
212219
}
213-
Object.assign(AsyncLogicEngine.prototype.truthy, { IDENTITY: true })
220+
Object.assign(AsyncLogicEngine.prototype.truthy, { [OriginalImpl]: true })
214221
export default AsyncLogicEngine

async_optimizer.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function getMethod (logic, engine, methodName, above) {
2828
}
2929

3030
let args = logic[methodName]
31-
if (!args || typeof args !== 'object') args = [args]
31+
if ((!args || typeof args !== 'object') && !method.optimizeUnary) args = [args]
3232

3333
if (Array.isArray(args)) {
3434
const optimizedArgs = args.map(l => optimize(l, engine, above))
@@ -50,12 +50,12 @@ function getMethod (logic, engine, methodName, above) {
5050

5151
if (isSync(optimizedArgs) && (method.method || method[Sync])) {
5252
const called = method.method ? method.method : method
53-
return declareSync((data, abv) => called(coerceArray(typeof optimizedArgs === 'function' ? optimizedArgs(data, abv) : optimizedArgs, method.optimizeUnary), data, abv || above, engine), true)
53+
if (method.optimizeUnary) return declareSync((data, abv) => called(typeof optimizedArgs === 'function' ? optimizedArgs(data, abv) : optimizedArgs, data, abv || above, engine.fallback), true)
54+
return declareSync((data, abv) => called(coerceArray(typeof optimizedArgs === 'function' ? optimizedArgs(data, abv) : optimizedArgs), data, abv || above, engine), true)
5455
}
5556

56-
return async (data, abv) => {
57-
return called(coerceArray(typeof optimizedArgs === 'function' ? await optimizedArgs(data, abv) : optimizedArgs, method.optimizeUnary), data, abv || above, engine)
58-
}
57+
if (method.optimizeUnary) return async (data, abv) => called(typeof optimizedArgs === 'function' ? await optimizedArgs(data, abv) : optimizedArgs, data, abv || above, engine)
58+
return async (data, abv) => called(coerceArray(typeof optimizedArgs === 'function' ? await optimizedArgs(data, abv) : optimizedArgs), data, abv || above, engine)
5959
}
6060
}
6161

compatibility.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { Sync } from './constants.js'
12
import defaultMethods from './defaultMethods.js'
23
const oldAll = defaultMethods.all
34

45
const all = {
6+
[Sync]: oldAll[Sync],
57
method: (args, context, above, engine) => {
68
if (Array.isArray(args)) {
79
const first = engine.run(args[0], context, above)

compiler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ function buildString (method, buildState = {}) {
205205
}
206206

207207
let coerce = engine.methods[func].optimizeUnary ? '' : 'coerceArray'
208-
if (!coerce && Array.isArray(lower) && lower.length === 1) lower = lower[0]
208+
if (!coerce && Array.isArray(lower) && lower.length === 1 && !Array.isArray(lower[0])) lower = lower[0]
209209
else if (coerce && Array.isArray(lower)) coerce = ''
210210

211211
const argumentsDict = [', context', ', context, above', ', context, above, engine']

constants.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
export const Sync = Symbol.for('json_logic_sync')
55
export const Compiled = Symbol.for('json_logic_compiled')
6-
export const EfficientTop = Symbol.for('json_logic_efficientTop')
6+
export const OriginalImpl = Symbol.for('json_logic_original')
7+
export const Unfound = Symbol.for('json_logic_unfound')
78

89
/**
910
* Checks if an item is synchronous.
@@ -22,6 +23,6 @@ export function isSync (item) {
2223

2324
export default {
2425
Sync,
25-
EfficientTop,
26+
OriginalImpl,
2627
isSync
2728
}

0 commit comments

Comments
 (0)