Skip to content
This repository was archived by the owner on Feb 4, 2025. It is now read-only.

Commit bbe1d8a

Browse files
committed
refactore: start applying visitors
1 parent 90da723 commit bbe1d8a

File tree

4 files changed

+114
-168
lines changed

4 files changed

+114
-168
lines changed

src/createJsonLogic.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,99 @@
1+
import isLogic from './isLogic';
2+
import getOperator from './getOperator';
3+
import truthy from './truthy';
4+
15
function createJsonLogic() {
6+
const operations = {}
7+
const visitors = {}
8+
9+
function addOperation(name, code) {
10+
operations[name] = code;
11+
}
12+
13+
function removeOperation(name) {
14+
delete operations[name];
15+
}
16+
17+
function addVisitor(name, code) {
18+
if (Array.isArray(name)) {
19+
name.forEach(addVisitor);
20+
}
21+
22+
visitors[name] = code;
23+
}
24+
25+
function removeVisitor(name) {
26+
if (Array.isArray(name)) {
27+
name.forEach(removeVisitor);
28+
}
29+
30+
delete visitors[name];
31+
}
32+
33+
function apply(logic, data) {
34+
// Does this array contain logic? Only one way to find out.
35+
if(Array.isArray(logic)) {
36+
return logic.map(function(l) {
37+
return apply(l, data);
38+
});
39+
}
40+
// You've recursed to a primitive, stop!
41+
if( ! isLogic(logic) ) {
42+
return logic;
43+
}
44+
45+
data = data || {};
46+
47+
var op = getOperator(logic);
48+
var values = logic[op];
49+
var i;
50+
var current;
51+
var scopedLogic, scopedData, filtered, initial;
52+
53+
// easy syntax for unary operators, like {"var" : "x"} instead of strict {"var" : ["x"]}
54+
if( ! Array.isArray(values)) {
55+
values = [values];
56+
}
57+
58+
// apply matching visitors first
59+
if (typeof visitors[op] === 'function') {
60+
return visitors[op](apply, data, values);
61+
}
62+
63+
// Everyone else gets immediate depth-first recursion
64+
values = values.map(function(val) {
65+
return apply(val, data);
66+
});
67+
68+
// The operation is called with "data" bound to its "this" and "values" passed as arguments.
69+
// Structured commands like % or > can name formal arguments while flexible commands (like missing or merge) can operate on the pseudo-array arguments
70+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
71+
if(typeof operations[op] === "function") {
72+
return operations[op].apply(data, values);
73+
}else if(op.indexOf(".") > 0) { // Contains a dot, and not in the 0th position
74+
var sub_ops = String(op).split(".");
75+
var operation = operations;
76+
for(i = 0; i < sub_ops.length; i++) {
77+
// Descending into operations
78+
operation = operation[sub_ops[i]];
79+
if(operation === undefined) {
80+
throw new Error("Unrecognized operation " + op +
81+
" (failed at " + sub_ops.slice(0, i+1).join(".") + ")");
82+
}
83+
}
84+
85+
return operation.apply(data, values);
86+
}
87+
88+
throw new Error("Unrecognized operation " + op );
89+
}
290

91+
return {
92+
add_operation: addOperation,
93+
rm_operation: removeOperation,
94+
add_visitor: addVisitor,
95+
rm_visitor: removeVisitor,
96+
}
397
}
498

599
export default createJsonLogic;

src/helpers/apply.js

Lines changed: 0 additions & 167 deletions
This file was deleted.

src/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import createJsonLogic from './createJsonLogic';
2+
import * as operations from './operations';
3+
import * as visitors from './visitors';
4+
5+
const jsonLogic = createJsonLogic();
6+
7+
Object.keys(operations).forEach(function(name) {
8+
const operation = operations[name];
9+
10+
jsonLogic.add_operation(operation.code || name , operation);
11+
});
12+
13+
Object.keys(visitors).forEach(function(name) {
14+
const visitor = visitors[name];
15+
16+
jsonLogic.add_visitor(visitor.code || name , visitor);
17+
});
18+
19+
export default jsonLogic;

src/visitors/condition.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ function condition(data, values) {
2727
return null;
2828
}
2929

30-
condition.code = 'if';
30+
condition.code = ['if', '?:'];
3131

3232
export default condition;

0 commit comments

Comments
 (0)