json-logic-engine
Advanced tools
Comparing version
@@ -25,5 +25,2 @@ // @ts-check | ||
* @property {Boolean} [useContext] | ||
* @property {Number} [varAccesses] | ||
* @property {Number} [varUseOverride] | ||
* @property {Boolean} [missingUsed] | ||
* @property {Boolean} [avoidInlineAsync] | ||
@@ -134,10 +131,13 @@ * | ||
buildState.useContext = buildState.useContext || (engine.methods[func] || {}).useContext | ||
if (typeof engine.methods[func] === 'function') { | ||
functions[func] = 1 | ||
buildState.useContext = buildState.useContext || (engine.methods[func] || {}).useContext | ||
asyncDetected = !isSync(engine.methods[func]) | ||
const inputStr = buildString(method[func], { ...buildState, avoidInlineAsync: true }) | ||
const stringBuildState = { ...buildState, avoidInlineAsync: true } | ||
const inputStr = buildString(method[func], stringBuildState) | ||
buildState.useContext = buildState.useContext || stringBuildState.useContext | ||
if (asyncDetected || inputStr.includes('await')) { | ||
@@ -153,3 +153,5 @@ buildState.asyncDetected = buildState.asyncDetected || asyncDetected | ||
asyncDetected = Boolean(async && engine.methods[func] && engine.methods[func].asyncMethod) | ||
const inputStr = buildString(method[func], { ...buildState, avoidInlineAsync: true }) | ||
const stringBuildState = { ...buildState, avoidInlineAsync: true } | ||
const inputStr = buildString(method[func], stringBuildState) | ||
buildState.useContext = buildState.useContext || stringBuildState.useContext | ||
@@ -168,2 +170,3 @@ if (asyncDetected || inputStr.startsWith('await')) { | ||
notTraversed.push(method[func]) | ||
buildState.useContext = true | ||
@@ -206,4 +209,7 @@ if (asyncDetected) { | ||
const func = method && Object.keys(method)[0] | ||
buildState.useContext = buildState.useContext || (engine.methods[func] || {}).useContext | ||
if (method && typeof method === 'object') { | ||
const func = Object.keys(method)[0] | ||
functions[func] = functions[func] || 2 | ||
@@ -248,3 +254,3 @@ | ||
const builder = engine.methods[func].asyncBuild || engine.methods[func].build | ||
const result = builder(method[func], state, above, engine) | ||
const result = builder(method[func], state, above, engine, buildState) | ||
methods.push(result) | ||
@@ -256,3 +262,3 @@ asyncDetected = !isSync(result) | ||
if (engine.methods[func].build) { | ||
methods.push(engine.methods[func].build(method[func], state, above, engine)) | ||
methods.push(engine.methods[func].build(method[func], state, above, engine, buildState)) | ||
return makeAsync(`methods[${methods.length - 1}]()`) | ||
@@ -280,4 +286,4 @@ } | ||
*/ | ||
function build (method, { notTraversed = [], functions = {}, methods = [], state = {}, engine, processing = [], async = engine.async, above = [], asyncDetected = false, values = [] } = {}) { | ||
const buildState = { notTraversed, functions, methods, state, async, engine, above, processing, asyncDetected, values } | ||
function build (method, buildState = {}) { | ||
Object.assign(buildState, Object.assign({ notTraversed: [], functions: {}, methods: [], state: {}, processing: [], async: buildState.engine.async, above: [], asyncDetected: false, values: [] }, buildState)) | ||
const str = buildString(method, buildState) | ||
@@ -293,7 +299,6 @@ return processBuiltString(method, str, buildState) | ||
*/ | ||
async function buildAsync (method, { notTraversed = [], functions = {}, methods = [], state = {}, engine, processing = [], async = engine.async, above = [], asyncDetected = false, values = [] } = {}) { | ||
const buildState = { notTraversed, functions, methods, state, async, engine, above, processing, asyncDetected, values } | ||
async function buildAsync (method, buildState = {}) { | ||
Object.assign(buildState, Object.assign({ notTraversed: [], functions: {}, methods: [], state: {}, processing: [], async: buildState.engine.async, above: [], asyncDetected: false, values: [] }, buildState)) | ||
const str = buildString(method, buildState) | ||
buildState.processing = await Promise.all(buildState.processing) | ||
// console.log(buildState.processing) | ||
return processBuiltString(method, str, buildState) | ||
@@ -338,4 +343,4 @@ } | ||
let copyStateCall = 'state[Override] = context;' | ||
if (!buildState.useContext && buildState.varUseOverride === buildState.varAccesses && buildState.varUseOverride) { | ||
// console.log(buildState.useContext) | ||
if (!buildState.useContext) { | ||
copyStateCall = '' | ||
@@ -345,10 +350,6 @@ while (str.includes('state[Override]')) { str = str.replace('state[Override]', 'context') } | ||
if (!buildState.useContext && !notTraversed.length && !buildState.varAccesses && !buildState.missingUsed && !Object.keys(buildState.methods).length) { | ||
copyStateCall = '' | ||
} | ||
const final = `${buildState.asyncDetected ? 'async' : ''} (context ${buildState.yieldUsed ? ', resumable = {}' : ''}) => { ${copyStateCall} const result = ${str}; return result }` | ||
// console.log(str) | ||
// console.log(final) | ||
console.log(final) | ||
@@ -355,0 +356,0 @@ // eslint-disable-next-line no-eval |
@@ -205,3 +205,5 @@ // @ts-check | ||
mapper = build(mapper, { ...buildState, state: {}, above: [selector, state, ...above], avoidInlineAsync: true }) | ||
const mapState = { ...buildState, state: {}, above: [selector, state, ...above], avoidInlineAsync: true } | ||
mapper = build(mapper, mapState) | ||
buildState.useContext = buildState.useContext || mapState.useContext | ||
buildState.methods.push(mapper) | ||
@@ -340,17 +342,2 @@ | ||
}, | ||
// build: ([selector, mapper], context, above, engine) => { | ||
// selector = build(selector, { | ||
// above: [selector, context, ...above], | ||
// engine, | ||
// avoidInlineAsync: true | ||
// }) || [] | ||
// mapper = build(mapper, { engine, state: {}, above: [selector, context, ...above], avoidInlineAsync: true }) | ||
// return () => { | ||
// return (typeof selector === 'function' ? selector(context) || [] : selector)[name](i => { | ||
// return typeof mapper === 'function' ? mapper(i) : mapper | ||
// }) | ||
// } | ||
// }, | ||
method: (input, context, above, engine) => { | ||
@@ -391,3 +378,6 @@ if (!Array.isArray(input)) throw new InvalidControlInput(input) | ||
selector = buildString(selector, buildState) | ||
mapper = build(mapper, { ...buildState, state: {}, above: [selector, state, ...above], avoidInlineAsync: true }) | ||
const mapState = { ...buildState, state: {}, above: [selector, state, ...above], avoidInlineAsync: true } | ||
mapper = build(mapper, mapState) | ||
buildState.useContext = buildState.useContext || mapState.useContext | ||
buildState.methods.push(mapper) | ||
@@ -404,26 +394,2 @@ | ||
}, | ||
// asyncBuild: ([selector, mapper], context, above, engine) => { | ||
// selector = build(selector, { | ||
// above, | ||
// engine, | ||
// async: true, | ||
// avoidInlineAsync: true | ||
// }) || [] | ||
// mapper = build(mapper, { engine, state: {}, above: [selector, context, ...above], async: true, avoidInlineAsync: true }) | ||
// if (isSync(selector) && isSync(mapper)) { | ||
// return declareSync(() => { | ||
// return (typeof selector === 'function' ? selector(context) || [] : selector)[name](i => { | ||
// return typeof mapper === 'function' ? mapper(i) : mapper | ||
// }) | ||
// }) | ||
// } | ||
// return async () => { | ||
// return asyncIterators[name](typeof selector === 'function' ? await selector(context) || [] : selector, i => { | ||
// return typeof mapper === 'function' ? mapper(i) : mapper | ||
// }) | ||
// } | ||
// }, | ||
traverse: false | ||
@@ -449,8 +415,5 @@ } | ||
// @ts-ignore Allow custom attribute | ||
defaultMethods.var.traverse = false | ||
// @ts-ignore Allow custom attribute | ||
defaultMethods.missing.deterministic = false | ||
// @ts-ignore Allow custom attribute | ||
defaultMethods.missing_some.deterministic = false | ||
Object.assign(defaultMethods.var, { traverse: false }) | ||
Object.assign(defaultMethods.missing, { deterministic: false, useContext: true }) | ||
Object.assign(defaultMethods.missing_some, { deterministic: false, useContext: true }) | ||
@@ -699,14 +662,2 @@ // @ts-ignore Allow custom attribute | ||
// @ts-ignore Allow custom attribute | ||
defaultMethods.missing.compile = function (data, buildState) { | ||
buildState.missingUsed = true | ||
return false | ||
} | ||
// @ts-ignore Allow custom attribute | ||
defaultMethods.missing_some.compile = function (data, buildState) { | ||
buildState.missingUsed = true | ||
return false | ||
} | ||
defaultMethods.none.deterministic = defaultMethods.some.deterministic | ||
@@ -742,5 +693,2 @@ | ||
let defaultValue = null | ||
buildState.varAccesses = (buildState.varAccesses || 0) + 1 | ||
buildState.varFallbacks = (buildState.varFallbacks || 0) | ||
buildState.varUseOverride = (buildState.varUseOverride || 0) | ||
buildState.varTop = buildState.varTop || new Set() | ||
@@ -756,3 +704,2 @@ if (!key || typeof data === 'string' || typeof data === 'number' || (Array.isArray(data) && data.length <= 2)) { | ||
// this allows for a small optimization :) | ||
buildState.varUseOverride++ | ||
return 'state[Override]' | ||
@@ -762,3 +709,3 @@ } | ||
if (typeof key !== 'string' && typeof key !== 'number') { | ||
buildState.varFallbacks++ | ||
buildState.useContext = true | ||
return false | ||
@@ -769,3 +716,3 @@ } | ||
if (key.includes('../')) { | ||
buildState.varFallbacks++ | ||
buildState.useContext = true | ||
return false | ||
@@ -787,3 +734,4 @@ } | ||
} | ||
buildState.varFallbacks++ | ||
buildState.useContext = true | ||
return false | ||
@@ -790,0 +738,0 @@ } |
{ | ||
"name": "json-logic-engine", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"description": "Construct complex rules with JSON & process them.", | ||
@@ -16,17 +16,19 @@ "main": "index.js", | ||
"devDependencies": { | ||
"eslint": "^7.15.0", | ||
"eslint-config-standard": "^16.0.2", | ||
"eslint-plugin-import": "^2.22.1", | ||
"coveralls": "^3.1.1", | ||
"eslint": "^7.32.0", | ||
"eslint-config-standard": "^16.0.3", | ||
"eslint-plugin-import": "^2.24.1", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-promise": "^4.2.1", | ||
"jest": "^26.6.3", | ||
"nyc": "^15.1.0", | ||
"coveralls": "^3.1.0" | ||
"nyc": "^15.1.0" | ||
}, | ||
"engines" : { "node" : ">=10.0.0" }, | ||
"engines": { | ||
"node": ">=10.0.0" | ||
}, | ||
"jest": { | ||
"testPathIgnorePatterns" : [ | ||
"./bench" | ||
"testPathIgnorePatterns": [ | ||
"./bench" | ||
] | ||
} | ||
} |
@@ -216,6 +216,9 @@ // @ts-check | ||
}, | ||
build: (input, context, above, engine) => { | ||
build: (input, context, above, engine, buildState) => { | ||
buildState.useContext = true | ||
return declareSync(() => result.method(input, context, above, engine)) | ||
}, | ||
asyncBuild: (input, context, above, engine) => { | ||
asyncBuild: (input, context, above, engine, buildState) => { | ||
buildState.useContext = true | ||
const [selector, mapper] = input | ||
@@ -222,0 +225,0 @@ |
257933
-0.71%11895
-0.38%