@jbrowse/jexl 2.3.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/LICENSE.txt +1 -0
- package/README.md +76 -74
- package/dist/Expression.d.ts +2 -12
- package/dist/Expression.js +5 -27
- package/dist/Expression.js.map +1 -1
- package/dist/Jexl.d.ts +6 -40
- package/dist/Jexl.js +7 -49
- package/dist/Jexl.js.map +1 -1
- package/dist/evaluator/Evaluator.d.ts +14 -55
- package/dist/evaluator/Evaluator.js +14 -73
- package/dist/evaluator/Evaluator.js.map +1 -1
- package/dist/evaluator/handlers.d.ts +19 -18
- package/dist/evaluator/handlers.js +54 -62
- package/dist/evaluator/handlers.js.map +1 -1
- package/dist/grammar.d.ts +3 -4
- package/dist/grammar.js +16 -39
- package/dist/grammar.js.map +1 -1
- package/esm/Expression.d.ts +2 -12
- package/esm/Expression.js +5 -27
- package/esm/Expression.js.map +1 -1
- package/esm/Jexl.d.ts +6 -40
- package/esm/Jexl.js +7 -49
- package/esm/Jexl.js.map +1 -1
- package/esm/evaluator/Evaluator.d.ts +14 -55
- package/esm/evaluator/Evaluator.js +14 -73
- package/esm/evaluator/Evaluator.js.map +1 -1
- package/esm/evaluator/handlers.d.ts +19 -18
- package/esm/evaluator/handlers.js +54 -62
- package/esm/evaluator/handlers.js.map +1 -1
- package/esm/grammar.d.ts +3 -4
- package/esm/grammar.js +16 -39
- package/esm/grammar.js.map +1 -1
- package/package.json +2 -1
- package/src/Expression.ts +5 -36
- package/src/Jexl.ts +7 -54
- package/src/evaluator/Evaluator.ts +14 -92
- package/src/evaluator/handlers.ts +54 -68
- package/src/grammar.ts +17 -38
- package/src/types.ts +4 -1
- package/dist/PromiseSync.d.ts +0 -13
- package/dist/PromiseSync.js +0 -80
- package/dist/PromiseSync.js.map +0 -1
- package/esm/PromiseSync.d.ts +0 -13
- package/esm/PromiseSync.js +0 -78
- package/esm/PromiseSync.js.map +0 -1
- package/src/PromiseSync.ts +0 -86
package/esm/Expression.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import PromiseSync from './PromiseSync.ts';
|
|
2
1
|
import type { AstNode } from './types.ts';
|
|
3
2
|
interface Grammar {
|
|
4
3
|
elements: Record<string, any>;
|
|
5
4
|
[key: string]: any;
|
|
6
5
|
}
|
|
7
|
-
type PromiseConstructor = typeof Promise | typeof PromiseSync;
|
|
8
6
|
declare class Expression {
|
|
9
7
|
_grammar: Grammar;
|
|
10
8
|
_exprStr: string;
|
|
@@ -18,21 +16,13 @@ declare class Expression {
|
|
|
18
16
|
*/
|
|
19
17
|
compile(): this;
|
|
20
18
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @param {Object} [context] A mapping of variables to values, which will be
|
|
23
|
-
* made accessible to the Jexl expression when evaluating it
|
|
24
|
-
* @returns {Promise<*>} resolves with the result of the evaluation.
|
|
25
|
-
*/
|
|
26
|
-
eval(context?: {}): Promise<any> | PromiseSync<any>;
|
|
27
|
-
/**
|
|
28
|
-
* Synchronously evaluates the expression within an optional context.
|
|
19
|
+
* Evaluates the expression within an optional context.
|
|
29
20
|
* @param {Object} [context] A mapping of variables to values, which will be
|
|
30
21
|
* made accessible to the Jexl expression when evaluating it
|
|
31
22
|
* @returns {*} the result of the evaluation.
|
|
32
23
|
* @throws {*} on error
|
|
33
24
|
*/
|
|
34
|
-
|
|
35
|
-
_eval(context: any, promise: PromiseConstructor): Promise<any> | PromiseSync<any>;
|
|
25
|
+
eval(context?: {}): any;
|
|
36
26
|
_getAst(): AstNode | null;
|
|
37
27
|
}
|
|
38
28
|
export default Expression;
|
package/esm/Expression.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Copyright 2020 Tom Shawver
|
|
4
4
|
*/
|
|
5
5
|
import Lexer from "./Lexer.js";
|
|
6
|
-
import PromiseSync from "./PromiseSync.js";
|
|
7
6
|
import Evaluator from "./evaluator/Evaluator.js";
|
|
8
7
|
import Parser from "./parser/Parser.js";
|
|
9
8
|
class Expression {
|
|
@@ -27,37 +26,16 @@ class Expression {
|
|
|
27
26
|
return this;
|
|
28
27
|
}
|
|
29
28
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @param {Object} [context] A mapping of variables to values, which will be
|
|
32
|
-
* made accessible to the Jexl expression when evaluating it
|
|
33
|
-
* @returns {Promise<*>} resolves with the result of the evaluation.
|
|
34
|
-
*/
|
|
35
|
-
eval(context = {}) {
|
|
36
|
-
return this._eval(context, Promise);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Synchronously evaluates the expression within an optional context.
|
|
29
|
+
* Evaluates the expression within an optional context.
|
|
40
30
|
* @param {Object} [context] A mapping of variables to values, which will be
|
|
41
31
|
* made accessible to the Jexl expression when evaluating it
|
|
42
32
|
* @returns {*} the result of the evaluation.
|
|
43
33
|
* @throws {*} on error
|
|
44
34
|
*/
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
throw res.error;
|
|
50
|
-
}
|
|
51
|
-
throw new Error(typeof res.error === 'string' ? res.error : JSON.stringify(res.error));
|
|
52
|
-
}
|
|
53
|
-
return res.value;
|
|
54
|
-
}
|
|
55
|
-
_eval(context, promise) {
|
|
56
|
-
return promise.resolve().then(() => {
|
|
57
|
-
const ast = this._getAst();
|
|
58
|
-
const evaluator = new Evaluator(this._grammar, context, undefined, promise);
|
|
59
|
-
return evaluator.eval(ast);
|
|
60
|
-
});
|
|
35
|
+
eval(context = {}) {
|
|
36
|
+
const ast = this._getAst();
|
|
37
|
+
const evaluator = new Evaluator(this._grammar, context);
|
|
38
|
+
return evaluator.eval(ast);
|
|
61
39
|
}
|
|
62
40
|
_getAst() {
|
|
63
41
|
if (!this._ast) {
|
package/esm/Expression.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Expression.js","sourceRoot":"","sources":["../src/Expression.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"Expression.js","sourceRoot":"","sources":["../src/Expression.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,SAAS,MAAM,0BAA0B,CAAA;AAChD,OAAO,MAAM,MAAM,oBAAoB,CAAA;AASvC,MAAM,UAAU;IAKd,YAAY,OAAgB,EAAE,OAAe;QAC3C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED;;;;;OAKG;IACH,OAAO;QACL,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC5C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,GAAG,EAAE;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;QAC1B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACvD,OAAO,SAAS,CAAC,IAAI,CAAC,GAAI,CAAC,CAAA;IAC7B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;CACF;AAED,eAAe,UAAU,CAAA"}
|
package/esm/Jexl.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import Expression from './Expression.ts';
|
|
|
2
2
|
interface Grammar {
|
|
3
3
|
elements: Record<string, any>;
|
|
4
4
|
functions: Record<string, (...args: any[]) => any>;
|
|
5
|
-
transforms: Record<string, (val: any, ...args: any[]) => any>;
|
|
6
5
|
}
|
|
7
6
|
/**
|
|
8
7
|
* Jexl is the Javascript Expression Language, capable of parsing and
|
|
@@ -26,13 +25,11 @@ declare class Jexl {
|
|
|
26
25
|
* @param {number} precedence The operator's precedence
|
|
27
26
|
* @param {function} fn A function to run to calculate the result. The function
|
|
28
27
|
* will be called with two arguments: left and right, denoting the values
|
|
29
|
-
* on either side of the operator. It should return
|
|
30
|
-
* value, or a Promise that resolves with the resulting value.
|
|
28
|
+
* on either side of the operator. It should return the resulting value.
|
|
31
29
|
* @param {boolean} [manualEval] If true, the `left` and `right` arguments
|
|
32
30
|
* will be wrapped in objects with an `eval` function. Calling
|
|
33
|
-
* left.eval() or right.eval() will return
|
|
34
|
-
*
|
|
35
|
-
* operands.
|
|
31
|
+
* left.eval() or right.eval() will return that operand's actual value.
|
|
32
|
+
* This is useful to conditionally evaluate operands.
|
|
36
33
|
*/
|
|
37
34
|
addBinaryOp(operator: string, precedence: number, fn: (left: any, right: any) => any, manualEval?: boolean): void;
|
|
38
35
|
/**
|
|
@@ -57,26 +54,9 @@ declare class Jexl {
|
|
|
57
54
|
* @param {string} operator The operator string to be added
|
|
58
55
|
* @param {function} fn A function to run to calculate the result. The function
|
|
59
56
|
* will be called with one argument: the literal value to the right of the
|
|
60
|
-
* operator. It should return
|
|
61
|
-
* that resolves with the resulting value.
|
|
57
|
+
* operator. It should return the resulting value.
|
|
62
58
|
*/
|
|
63
59
|
addUnaryOp(operator: string, fn: (right: any) => any): void;
|
|
64
|
-
/**
|
|
65
|
-
* Adds or replaces a transform function in this Jexl instance.
|
|
66
|
-
* @param {string} name The name of the transform function, as it will be used
|
|
67
|
-
* within Jexl expressions
|
|
68
|
-
* @param {function} fn The function to be executed when this transform is
|
|
69
|
-
* invoked. It will be provided with at least one argument:
|
|
70
|
-
* - {*} value: The value to be transformed
|
|
71
|
-
* - {...*} args: The arguments for this transform
|
|
72
|
-
*/
|
|
73
|
-
addTransform(name: string, fn: (val: any, ...args: any[]) => any): void;
|
|
74
|
-
/**
|
|
75
|
-
* Syntactic sugar for calling {@link #addTransform} repeatedly. This function
|
|
76
|
-
* accepts a map of one or more transform names to their transform function.
|
|
77
|
-
* @param {{}} map A map of transform names to transform functions
|
|
78
|
-
*/
|
|
79
|
-
addTransforms(map: Record<string, (val: any, ...args: any[]) => any>): void;
|
|
80
60
|
/**
|
|
81
61
|
* Creates an Expression object from the given Jexl expression string, and
|
|
82
62
|
* immediately compiles it. The returned Expression object can then be
|
|
@@ -100,28 +80,14 @@ declare class Jexl {
|
|
|
100
80
|
*/
|
|
101
81
|
getFunction(name: string): (...args: any[]) => any;
|
|
102
82
|
/**
|
|
103
|
-
*
|
|
104
|
-
* @param {string} name The name of the transform function
|
|
105
|
-
* @returns {function} The transform function
|
|
106
|
-
*/
|
|
107
|
-
getTransform(name: string): (val: any, ...args: any[]) => any;
|
|
108
|
-
/**
|
|
109
|
-
* Asynchronously evaluates a Jexl string within an optional context.
|
|
110
|
-
* @param {string} expression The Jexl expression to be evaluated
|
|
111
|
-
* @param {Object} [context] A mapping of variables to values, which will be
|
|
112
|
-
* made accessible to the Jexl expression when evaluating it
|
|
113
|
-
* @returns {Promise<*>} resolves with the result of the evaluation.
|
|
114
|
-
*/
|
|
115
|
-
eval(expression: string, context?: {}): Promise<any> | import("./PromiseSync.ts").default<any>;
|
|
116
|
-
/**
|
|
117
|
-
* Synchronously evaluates a Jexl string within an optional context.
|
|
83
|
+
* Evaluates a Jexl string within an optional context.
|
|
118
84
|
* @param {string} expression The Jexl expression to be evaluated
|
|
119
85
|
* @param {Object} [context] A mapping of variables to values, which will be
|
|
120
86
|
* made accessible to the Jexl expression when evaluating it
|
|
121
87
|
* @returns {*} the result of the evaluation.
|
|
122
88
|
* @throws {*} on error
|
|
123
89
|
*/
|
|
124
|
-
|
|
90
|
+
eval(expression: string, context?: {}): any;
|
|
125
91
|
/**
|
|
126
92
|
* A JavaScript template literal to allow expressions to be defined by the
|
|
127
93
|
* syntax: expr`40 + 2`
|
package/esm/Jexl.js
CHANGED
|
@@ -28,13 +28,11 @@ class Jexl {
|
|
|
28
28
|
* @param {number} precedence The operator's precedence
|
|
29
29
|
* @param {function} fn A function to run to calculate the result. The function
|
|
30
30
|
* will be called with two arguments: left and right, denoting the values
|
|
31
|
-
* on either side of the operator. It should return
|
|
32
|
-
* value, or a Promise that resolves with the resulting value.
|
|
31
|
+
* on either side of the operator. It should return the resulting value.
|
|
33
32
|
* @param {boolean} [manualEval] If true, the `left` and `right` arguments
|
|
34
33
|
* will be wrapped in objects with an `eval` function. Calling
|
|
35
|
-
* left.eval() or right.eval() will return
|
|
36
|
-
*
|
|
37
|
-
* operands.
|
|
34
|
+
* left.eval() or right.eval() will return that operand's actual value.
|
|
35
|
+
* This is useful to conditionally evaluate operands.
|
|
38
36
|
*/
|
|
39
37
|
addBinaryOp(operator, precedence, fn, manualEval) {
|
|
40
38
|
this._addGrammarElement(operator, {
|
|
@@ -69,8 +67,7 @@ class Jexl {
|
|
|
69
67
|
* @param {string} operator The operator string to be added
|
|
70
68
|
* @param {function} fn A function to run to calculate the result. The function
|
|
71
69
|
* will be called with one argument: the literal value to the right of the
|
|
72
|
-
* operator. It should return
|
|
73
|
-
* that resolves with the resulting value.
|
|
70
|
+
* operator. It should return the resulting value.
|
|
74
71
|
*/
|
|
75
72
|
addUnaryOp(operator, fn) {
|
|
76
73
|
this._addGrammarElement(operator, {
|
|
@@ -79,26 +76,6 @@ class Jexl {
|
|
|
79
76
|
eval: fn
|
|
80
77
|
});
|
|
81
78
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Adds or replaces a transform function in this Jexl instance.
|
|
84
|
-
* @param {string} name The name of the transform function, as it will be used
|
|
85
|
-
* within Jexl expressions
|
|
86
|
-
* @param {function} fn The function to be executed when this transform is
|
|
87
|
-
* invoked. It will be provided with at least one argument:
|
|
88
|
-
* - {*} value: The value to be transformed
|
|
89
|
-
* - {...*} args: The arguments for this transform
|
|
90
|
-
*/
|
|
91
|
-
addTransform(name, fn) {
|
|
92
|
-
this._grammar.transforms[name] = fn;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Syntactic sugar for calling {@link #addTransform} repeatedly. This function
|
|
96
|
-
* accepts a map of one or more transform names to their transform function.
|
|
97
|
-
* @param {{}} map A map of transform names to transform functions
|
|
98
|
-
*/
|
|
99
|
-
addTransforms(map) {
|
|
100
|
-
Object.assign(this._grammar.transforms, map);
|
|
101
|
-
}
|
|
102
79
|
/**
|
|
103
80
|
* Creates an Expression object from the given Jexl expression string, and
|
|
104
81
|
* immediately compiles it. The returned Expression object can then be
|
|
@@ -129,35 +106,16 @@ class Jexl {
|
|
|
129
106
|
return this._grammar.functions[name];
|
|
130
107
|
}
|
|
131
108
|
/**
|
|
132
|
-
*
|
|
133
|
-
* @param {string} name The name of the transform function
|
|
134
|
-
* @returns {function} The transform function
|
|
135
|
-
*/
|
|
136
|
-
getTransform(name) {
|
|
137
|
-
return this._grammar.transforms[name];
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Asynchronously evaluates a Jexl string within an optional context.
|
|
141
|
-
* @param {string} expression The Jexl expression to be evaluated
|
|
142
|
-
* @param {Object} [context] A mapping of variables to values, which will be
|
|
143
|
-
* made accessible to the Jexl expression when evaluating it
|
|
144
|
-
* @returns {Promise<*>} resolves with the result of the evaluation.
|
|
145
|
-
*/
|
|
146
|
-
eval(expression, context = {}) {
|
|
147
|
-
const exprObj = this.createExpression(expression);
|
|
148
|
-
return exprObj.eval(context);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Synchronously evaluates a Jexl string within an optional context.
|
|
109
|
+
* Evaluates a Jexl string within an optional context.
|
|
152
110
|
* @param {string} expression The Jexl expression to be evaluated
|
|
153
111
|
* @param {Object} [context] A mapping of variables to values, which will be
|
|
154
112
|
* made accessible to the Jexl expression when evaluating it
|
|
155
113
|
* @returns {*} the result of the evaluation.
|
|
156
114
|
* @throws {*} on error
|
|
157
115
|
*/
|
|
158
|
-
|
|
116
|
+
eval(expression, context = {}) {
|
|
159
117
|
const exprObj = this.createExpression(expression);
|
|
160
|
-
return exprObj.
|
|
118
|
+
return exprObj.eval(context);
|
|
161
119
|
}
|
|
162
120
|
/**
|
|
163
121
|
* A JavaScript template literal to allow expressions to be defined by the
|
package/esm/Jexl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Jexl.js","sourceRoot":"","sources":["../src/Jexl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"Jexl.js","sourceRoot":"","sources":["../src/Jexl.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,6 @@ interface Grammar {
|
|
|
3
3
|
elements: Record<string, any>;
|
|
4
4
|
[key: string]: any;
|
|
5
5
|
}
|
|
6
|
-
type PromiseConstructor = typeof Promise | any;
|
|
7
6
|
/**
|
|
8
7
|
* The Evaluator takes a Jexl expression tree as generated by the
|
|
9
8
|
* {@link Parser} and calculates its value within a given context. The
|
|
@@ -15,78 +14,38 @@ type PromiseConstructor = typeof Promise | any;
|
|
|
15
14
|
* @param {{}} grammar A grammar object against which to evaluate the expression
|
|
16
15
|
* tree
|
|
17
16
|
* @param {{}} [context] A map of variable keys to their values. This will be
|
|
18
|
-
* accessed to resolve the value of each non-relative identifier.
|
|
19
|
-
* Promise values will be passed to the expression as their resolved
|
|
20
|
-
* value.
|
|
17
|
+
* accessed to resolve the value of each non-relative identifier.
|
|
21
18
|
* @param {{}|Array<{}|Array>} [relativeContext] A map or array to be accessed
|
|
22
19
|
* to resolve the value of a relative identifier.
|
|
23
|
-
* @param {function} promise A constructor for the Promise class to be used;
|
|
24
|
-
* probably either Promise or PromiseSync.
|
|
25
20
|
*/
|
|
26
21
|
declare class Evaluator {
|
|
27
22
|
_grammar: Grammar;
|
|
28
23
|
_context: any;
|
|
29
24
|
_relContext: any;
|
|
30
|
-
|
|
31
|
-
constructor(grammar: Grammar, context?: any, relativeContext?: any, promise?: PromiseConstructor);
|
|
25
|
+
constructor(grammar: Grammar, context?: any, relativeContext?: any);
|
|
32
26
|
/**
|
|
33
27
|
* Evaluates an expression tree within the configured context.
|
|
34
28
|
* @param {{}} ast An expression tree object
|
|
35
|
-
* @returns {
|
|
29
|
+
* @returns {*} the resulting value of the expression.
|
|
36
30
|
*/
|
|
37
31
|
eval(ast: AstNode): any;
|
|
38
32
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
33
|
+
* Evaluates each expression within an array, and delivers the response as an
|
|
34
|
+
* array with the resulting values at the same indexes as their originating
|
|
35
|
+
* expressions.
|
|
42
36
|
* @param {Array<string>} arr An array of expression strings to be evaluated
|
|
43
|
-
* @returns {
|
|
37
|
+
* @returns {Array<{}>} the result array
|
|
44
38
|
*/
|
|
45
|
-
evalArray(arr: AstNode[]): any;
|
|
39
|
+
evalArray(arr: AstNode[]): any[];
|
|
46
40
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* as their value.
|
|
41
|
+
* Evaluates each expression within a map, and delivers the response as a map
|
|
42
|
+
* with the same keys, but with the evaluated result for each as their value.
|
|
50
43
|
* @param {{}} map A map of expression names to expression trees to be
|
|
51
44
|
* evaluated
|
|
52
|
-
* @returns {
|
|
45
|
+
* @returns {{}} the result map.
|
|
53
46
|
*/
|
|
54
|
-
evalMap(map: Record<string, AstNode>):
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* The intent is for the subject to be an array of subjects that will be
|
|
58
|
-
* individually used as the relative context against the provided expression
|
|
59
|
-
* tree. Only the elements whose expressions result in a truthy value will be
|
|
60
|
-
* included in the resulting array.
|
|
61
|
-
*
|
|
62
|
-
* If the subject is not an array of values, it will be converted to a single-
|
|
63
|
-
* element array before running the filter.
|
|
64
|
-
* @param {*} subject The value to be filtered usually an array. If this value is
|
|
65
|
-
* not an array, it will be converted to an array with this value as the
|
|
66
|
-
* only element.
|
|
67
|
-
* @param {{}} expr The expression tree to run against each subject. If the
|
|
68
|
-
* tree evaluates to a truthy result, then the value will be included in
|
|
69
|
-
* the returned array otherwise, it will be eliminated.
|
|
70
|
-
* @returns {Promise<Array>} resolves with an array of values that passed the
|
|
71
|
-
* expression filter.
|
|
72
|
-
* @private
|
|
73
|
-
*/
|
|
74
|
-
_filterRelative(subject: any, expr: AstNode): any;
|
|
75
|
-
/**
|
|
76
|
-
* Applies a static filter expression to a subject value. If the filter
|
|
77
|
-
* expression evaluates to boolean true, the subject is returned if false,
|
|
78
|
-
* undefined.
|
|
79
|
-
*
|
|
80
|
-
* For any other resulting value of the expression, this function will attempt
|
|
81
|
-
* to respond with the property at that name or index of the subject.
|
|
82
|
-
* @param {*} subject The value to be filtered. Usually an Array (for which
|
|
83
|
-
* the expression would generally resolve to a numeric index) or an
|
|
84
|
-
* Object (for which the expression would generally resolve to a string
|
|
85
|
-
* indicating a property name)
|
|
86
|
-
* @param {{}} expr The expression tree to run against the subject
|
|
87
|
-
* @returns {Promise<*>} resolves with the value of the drill-down.
|
|
88
|
-
* @private
|
|
89
|
-
*/
|
|
90
|
-
_filterStatic(subject: any, expr: AstNode): any;
|
|
47
|
+
evalMap(map: Record<string, AstNode>): {
|
|
48
|
+
[k: string]: any;
|
|
49
|
+
};
|
|
91
50
|
}
|
|
92
51
|
export default Evaluator;
|
|
@@ -14,104 +14,45 @@ import * as handlers from "./handlers.js";
|
|
|
14
14
|
* @param {{}} grammar A grammar object against which to evaluate the expression
|
|
15
15
|
* tree
|
|
16
16
|
* @param {{}} [context] A map of variable keys to their values. This will be
|
|
17
|
-
* accessed to resolve the value of each non-relative identifier.
|
|
18
|
-
* Promise values will be passed to the expression as their resolved
|
|
19
|
-
* value.
|
|
17
|
+
* accessed to resolve the value of each non-relative identifier.
|
|
20
18
|
* @param {{}|Array<{}|Array>} [relativeContext] A map or array to be accessed
|
|
21
19
|
* to resolve the value of a relative identifier.
|
|
22
|
-
* @param {function} promise A constructor for the Promise class to be used;
|
|
23
|
-
* probably either Promise or PromiseSync.
|
|
24
20
|
*/
|
|
25
21
|
class Evaluator {
|
|
26
|
-
constructor(grammar, context, relativeContext
|
|
22
|
+
constructor(grammar, context, relativeContext) {
|
|
27
23
|
this._grammar = grammar;
|
|
28
24
|
this._context = context || {};
|
|
29
25
|
this._relContext = relativeContext || this._context;
|
|
30
|
-
this.Promise = promise;
|
|
31
26
|
}
|
|
32
27
|
/**
|
|
33
28
|
* Evaluates an expression tree within the configured context.
|
|
34
29
|
* @param {{}} ast An expression tree object
|
|
35
|
-
* @returns {
|
|
30
|
+
* @returns {*} the resulting value of the expression.
|
|
36
31
|
*/
|
|
37
32
|
eval(ast) {
|
|
38
|
-
return
|
|
39
|
-
return handlers[ast.type].call(this, ast);
|
|
40
|
-
});
|
|
33
|
+
return handlers[ast.type].call(this, ast);
|
|
41
34
|
}
|
|
42
35
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
36
|
+
* Evaluates each expression within an array, and delivers the response as an
|
|
37
|
+
* array with the resulting values at the same indexes as their originating
|
|
38
|
+
* expressions.
|
|
46
39
|
* @param {Array<string>} arr An array of expression strings to be evaluated
|
|
47
|
-
* @returns {
|
|
40
|
+
* @returns {Array<{}>} the result array
|
|
48
41
|
*/
|
|
49
42
|
evalArray(arr) {
|
|
50
|
-
return
|
|
43
|
+
return arr.map((elem) => this.eval(elem));
|
|
51
44
|
}
|
|
52
45
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* as their value.
|
|
46
|
+
* Evaluates each expression within a map, and delivers the response as a map
|
|
47
|
+
* with the same keys, but with the evaluated result for each as their value.
|
|
56
48
|
* @param {{}} map A map of expression names to expression trees to be
|
|
57
49
|
* evaluated
|
|
58
|
-
* @returns {
|
|
50
|
+
* @returns {{}} the result map.
|
|
59
51
|
*/
|
|
60
52
|
evalMap(map) {
|
|
61
53
|
const entries = Object.entries(map);
|
|
62
|
-
const
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Applies a filter expression with relative identifier elements to a subject.
|
|
67
|
-
* The intent is for the subject to be an array of subjects that will be
|
|
68
|
-
* individually used as the relative context against the provided expression
|
|
69
|
-
* tree. Only the elements whose expressions result in a truthy value will be
|
|
70
|
-
* included in the resulting array.
|
|
71
|
-
*
|
|
72
|
-
* If the subject is not an array of values, it will be converted to a single-
|
|
73
|
-
* element array before running the filter.
|
|
74
|
-
* @param {*} subject The value to be filtered usually an array. If this value is
|
|
75
|
-
* not an array, it will be converted to an array with this value as the
|
|
76
|
-
* only element.
|
|
77
|
-
* @param {{}} expr The expression tree to run against each subject. If the
|
|
78
|
-
* tree evaluates to a truthy result, then the value will be included in
|
|
79
|
-
* the returned array otherwise, it will be eliminated.
|
|
80
|
-
* @returns {Promise<Array>} resolves with an array of values that passed the
|
|
81
|
-
* expression filter.
|
|
82
|
-
* @private
|
|
83
|
-
*/
|
|
84
|
-
_filterRelative(subject, expr) {
|
|
85
|
-
const arr = Array.isArray(subject)
|
|
86
|
-
? subject
|
|
87
|
-
: subject == null
|
|
88
|
-
? []
|
|
89
|
-
: [subject];
|
|
90
|
-
const promises = arr.map((elem) => new Evaluator(this._grammar, this._context, elem, this.Promise).eval(expr));
|
|
91
|
-
return this.Promise.all(promises).then((values) => arr.filter((_, idx) => values[idx]));
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Applies a static filter expression to a subject value. If the filter
|
|
95
|
-
* expression evaluates to boolean true, the subject is returned if false,
|
|
96
|
-
* undefined.
|
|
97
|
-
*
|
|
98
|
-
* For any other resulting value of the expression, this function will attempt
|
|
99
|
-
* to respond with the property at that name or index of the subject.
|
|
100
|
-
* @param {*} subject The value to be filtered. Usually an Array (for which
|
|
101
|
-
* the expression would generally resolve to a numeric index) or an
|
|
102
|
-
* Object (for which the expression would generally resolve to a string
|
|
103
|
-
* indicating a property name)
|
|
104
|
-
* @param {{}} expr The expression tree to run against the subject
|
|
105
|
-
* @returns {Promise<*>} resolves with the value of the drill-down.
|
|
106
|
-
* @private
|
|
107
|
-
*/
|
|
108
|
-
_filterStatic(subject, expr) {
|
|
109
|
-
return this.eval(expr).then((res) => {
|
|
110
|
-
if (typeof res === 'boolean') {
|
|
111
|
-
return res ? subject : undefined;
|
|
112
|
-
}
|
|
113
|
-
return subject?.[res];
|
|
114
|
-
});
|
|
54
|
+
const vals = entries.map(([_, ast]) => this.eval(ast));
|
|
55
|
+
return Object.fromEntries(entries.map(([key], idx) => [key, vals[idx]]));
|
|
115
56
|
}
|
|
116
57
|
}
|
|
117
58
|
export default Evaluator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Evaluator.js","sourceRoot":"","sources":["../../src/evaluator/Evaluator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"Evaluator.js","sourceRoot":"","sources":["../../src/evaluator/Evaluator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AASzC;;;;;;;;;;;;;;GAcG;AACH,MAAM,SAAS;IAKb,YAAY,OAAgB,EAAE,OAAa,EAAE,eAAqB;QAChE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,IAAI,CAAC,QAAQ,GAAG,OAAO,IAAI,EAAE,CAAA;QAC7B,IAAI,CAAC,WAAW,GAAG,eAAe,IAAI,IAAI,CAAC,QAAQ,CAAA;IACrD,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,GAAY;QACf,OAAQ,QAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACpD,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,GAAc;QACtB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAa,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACpD,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,GAA4B;QAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACtD,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1E,CAAC;CACF;AAED,eAAe,SAAS,CAAA"}
|
|
@@ -4,30 +4,30 @@ import type Evaluator from './Evaluator.ts';
|
|
|
4
4
|
* independently run through the evaluator.
|
|
5
5
|
* @param {{type: 'ObjectLiteral', value: <{}>}} ast An expression tree with an
|
|
6
6
|
* ObjectLiteral as the top node
|
|
7
|
-
* @returns {
|
|
7
|
+
* @returns {[]} an array of evaluated values.
|
|
8
8
|
* @private
|
|
9
9
|
*/
|
|
10
|
-
export declare function ArrayLiteral(this: Evaluator, ast: any): any;
|
|
10
|
+
export declare function ArrayLiteral(this: Evaluator, ast: any): any[];
|
|
11
11
|
/**
|
|
12
12
|
* Evaluates a BinaryExpression node by running the Grammar's evaluator for
|
|
13
13
|
* the given operator. Note that binary expressions support two types of
|
|
14
14
|
* evaluators: `eval` is called with the left and right operands pre-evaluated.
|
|
15
15
|
* `evalOnDemand`, if it exists, will be called with the left and right operands
|
|
16
16
|
* each individually wrapped in an object with an "eval" function that returns
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* the resulting value. This allows the binary expression to evaluate the
|
|
18
|
+
* operands conditionally.
|
|
19
19
|
* @param {{type: 'BinaryExpression', operator: <string>, left: {},
|
|
20
20
|
* right: {}}} ast An expression tree with a BinaryExpression as the top
|
|
21
21
|
* node
|
|
22
|
-
* @returns {
|
|
22
|
+
* @returns {*} the value of the BinaryExpression.
|
|
23
23
|
* @private
|
|
24
24
|
*/
|
|
25
25
|
export declare function BinaryExpression(this: Evaluator, ast: any): any;
|
|
26
26
|
/**
|
|
27
27
|
* Evaluates a ConditionalExpression node by first evaluating its test branch,
|
|
28
|
-
* and
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* and returning the consequent branch if the test is truthy, or the alternate
|
|
29
|
+
* branch if it is not. If there is no consequent branch, the test result will
|
|
30
|
+
* be used instead.
|
|
31
31
|
* @param {{type: 'ConditionalExpression', test: {}, consequent: {},
|
|
32
32
|
* alternate: {}}} ast An expression tree with a ConditionalExpression as
|
|
33
33
|
* the top node
|
|
@@ -35,11 +35,12 @@ export declare function BinaryExpression(this: Evaluator, ast: any): any;
|
|
|
35
35
|
*/
|
|
36
36
|
export declare function ConditionalExpression(this: Evaluator, ast: any): any;
|
|
37
37
|
/**
|
|
38
|
-
* Evaluates a FilterExpression by applying
|
|
38
|
+
* Evaluates a FilterExpression by applying bracket notation for array/object access.
|
|
39
|
+
* Note: Relative filtering (with leading dot) is not supported.
|
|
39
40
|
* @param {{type: 'FilterExpression', relative: <boolean>, expr: {},
|
|
40
41
|
* subject: {}}} ast An expression tree with a FilterExpression as the top
|
|
41
42
|
* node
|
|
42
|
-
* @returns {
|
|
43
|
+
* @returns {*} the value at the specified index/property.
|
|
43
44
|
* @private
|
|
44
45
|
*/
|
|
45
46
|
export declare function FilterExpression(this: Evaluator, ast: any): any;
|
|
@@ -49,8 +50,7 @@ export declare function FilterExpression(this: Evaluator, ast: any): any;
|
|
|
49
50
|
* constructed.
|
|
50
51
|
* @param {{type: 'Identifier', value: <string>, [from]: {}}} ast An expression
|
|
51
52
|
* tree with an Identifier as the top node
|
|
52
|
-
* @returns {
|
|
53
|
-
* will resolve with the identifier's value.
|
|
53
|
+
* @returns {*} the identifier's value.
|
|
54
54
|
* @private
|
|
55
55
|
*/
|
|
56
56
|
export declare function Identifier(this: Evaluator, ast: any): any;
|
|
@@ -67,7 +67,7 @@ export declare function Literal(this: Evaluator, ast: any): any;
|
|
|
67
67
|
* and concatenating all parts into a final string.
|
|
68
68
|
* @param {{type: 'TemplateLiteral', parts: Array<{}>}} ast An expression
|
|
69
69
|
* tree with a TemplateLiteral as the top node
|
|
70
|
-
* @returns {
|
|
70
|
+
* @returns {string} the final interpolated string
|
|
71
71
|
* @private
|
|
72
72
|
*/
|
|
73
73
|
export declare function TemplateLiteral(this: Evaluator, ast: any): any;
|
|
@@ -76,17 +76,18 @@ export declare function TemplateLiteral(this: Evaluator, ast: any): any;
|
|
|
76
76
|
* independently run through the evaluator.
|
|
77
77
|
* @param {{type: 'ObjectLiteral', value: <{}>}} ast An expression tree with an
|
|
78
78
|
* ObjectLiteral as the top node
|
|
79
|
-
* @returns {
|
|
79
|
+
* @returns {{}} a map of evaluated values.
|
|
80
80
|
* @private
|
|
81
81
|
*/
|
|
82
|
-
export declare function ObjectLiteral(this: Evaluator, ast: any):
|
|
82
|
+
export declare function ObjectLiteral(this: Evaluator, ast: any): {
|
|
83
|
+
[k: string]: any;
|
|
84
|
+
};
|
|
83
85
|
/**
|
|
84
86
|
* Evaluates a FunctionCall node by applying the supplied arguments to a
|
|
85
87
|
* function defined in one of the grammar's function pools.
|
|
86
88
|
* @param {{type: 'FunctionCall', name: <string>}} ast An
|
|
87
89
|
* expression tree with a FunctionCall as the top node
|
|
88
|
-
* @returns {
|
|
89
|
-
* will resolve with the resulting value.
|
|
90
|
+
* @returns {*} the value of the function call.
|
|
90
91
|
* @private
|
|
91
92
|
*/
|
|
92
93
|
export declare function FunctionCall(this: Evaluator, ast: any): any;
|
|
@@ -95,7 +96,7 @@ export declare function FunctionCall(this: Evaluator, ast: any): any;
|
|
|
95
96
|
* operator's eval function.
|
|
96
97
|
* @param {{type: 'UnaryExpression', operator: <string>, right: {}}} ast An
|
|
97
98
|
* expression tree with a UnaryExpression as the top node
|
|
98
|
-
* @returns {
|
|
99
|
+
* @returns {*} the value of the UnaryExpression.
|
|
99
100
|
* @constructor
|
|
100
101
|
*/
|
|
101
102
|
export declare function UnaryExpression(this: Evaluator, ast: any): any;
|