@jbrowse/jexl 2.3.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/LICENSE.txt +19 -0
  3. package/README.md +216 -0
  4. package/dist/Expression.d.ts +38 -0
  5. package/dist/Expression.js +75 -0
  6. package/dist/Expression.js.map +1 -0
  7. package/dist/Jexl.d.ts +148 -0
  8. package/dist/Jexl.js +208 -0
  9. package/dist/Jexl.js.map +1 -0
  10. package/dist/Lexer.d.ts +130 -0
  11. package/dist/Lexer.js +321 -0
  12. package/dist/Lexer.js.map +1 -0
  13. package/dist/PromiseSync.d.ts +13 -0
  14. package/dist/PromiseSync.js +80 -0
  15. package/dist/PromiseSync.js.map +1 -0
  16. package/dist/evaluator/Evaluator.d.ts +92 -0
  17. package/dist/evaluator/Evaluator.js +153 -0
  18. package/dist/evaluator/Evaluator.js.map +1 -0
  19. package/dist/evaluator/handlers.d.ts +111 -0
  20. package/dist/evaluator/handlers.js +216 -0
  21. package/dist/evaluator/handlers.js.map +1 -0
  22. package/dist/grammar.d.ts +25 -0
  23. package/dist/grammar.js +179 -0
  24. package/dist/grammar.js.map +1 -0
  25. package/dist/index.d.ts +5 -0
  26. package/dist/index.js +20 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/package.json +1 -0
  29. package/dist/parser/Parser.d.ts +112 -0
  30. package/dist/parser/Parser.js +233 -0
  31. package/dist/parser/Parser.js.map +1 -0
  32. package/dist/parser/handlers.d.ts +112 -0
  33. package/dist/parser/handlers.js +302 -0
  34. package/dist/parser/handlers.js.map +1 -0
  35. package/dist/parser/states.d.ts +47 -0
  36. package/dist/parser/states.js +195 -0
  37. package/dist/parser/states.js.map +1 -0
  38. package/dist/types.d.ts +77 -0
  39. package/dist/types.js +7 -0
  40. package/dist/types.js.map +1 -0
  41. package/esm/Expression.d.ts +38 -0
  42. package/esm/Expression.js +70 -0
  43. package/esm/Expression.js.map +1 -0
  44. package/esm/Jexl.d.ts +148 -0
  45. package/esm/Jexl.js +202 -0
  46. package/esm/Jexl.js.map +1 -0
  47. package/esm/Lexer.d.ts +130 -0
  48. package/esm/Lexer.js +319 -0
  49. package/esm/Lexer.js.map +1 -0
  50. package/esm/PromiseSync.d.ts +13 -0
  51. package/esm/PromiseSync.js +78 -0
  52. package/esm/PromiseSync.js.map +1 -0
  53. package/esm/evaluator/Evaluator.d.ts +92 -0
  54. package/esm/evaluator/Evaluator.js +118 -0
  55. package/esm/evaluator/Evaluator.js.map +1 -0
  56. package/esm/evaluator/handlers.d.ts +111 -0
  57. package/esm/evaluator/handlers.js +202 -0
  58. package/esm/evaluator/handlers.js.map +1 -0
  59. package/esm/grammar.d.ts +25 -0
  60. package/esm/grammar.js +175 -0
  61. package/esm/grammar.js.map +1 -0
  62. package/esm/index.d.ts +5 -0
  63. package/esm/index.js +9 -0
  64. package/esm/index.js.map +1 -0
  65. package/esm/parser/Parser.d.ts +112 -0
  66. package/esm/parser/Parser.js +198 -0
  67. package/esm/parser/Parser.js.map +1 -0
  68. package/esm/parser/handlers.d.ts +112 -0
  69. package/esm/parser/handlers.js +280 -0
  70. package/esm/parser/handlers.js.map +1 -0
  71. package/esm/parser/states.d.ts +47 -0
  72. package/esm/parser/states.js +159 -0
  73. package/esm/parser/states.js.map +1 -0
  74. package/esm/types.d.ts +77 -0
  75. package/esm/types.js +6 -0
  76. package/esm/types.js.map +1 -0
  77. package/package.json +67 -0
  78. package/src/Expression.ts +95 -0
  79. package/src/Jexl.ts +232 -0
  80. package/src/Lexer.ts +344 -0
  81. package/src/PromiseSync.ts +86 -0
  82. package/src/evaluator/Evaluator.ts +153 -0
  83. package/src/evaluator/handlers.ts +226 -0
  84. package/src/grammar.ts +200 -0
  85. package/src/index.ts +10 -0
  86. package/src/parser/Parser.ts +235 -0
  87. package/src/parser/handlers.ts +309 -0
  88. package/src/parser/states.ts +177 -0
  89. package/src/types.ts +107 -0
package/esm/Lexer.js ADDED
@@ -0,0 +1,319 @@
1
+ /*
2
+ * Jexl
3
+ * Copyright 2020 Tom Shawver
4
+ */
5
+ const numericRegex = /^-?(?:(?:[0-9]*\.[0-9]+)|[0-9]+)$/;
6
+ const identRegex = /^[a-zA-Zа-яА-Я_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF$][a-zA-Zа-яА-Я0-9_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF$]*$/;
7
+ const escEscRegex = /\\\\/;
8
+ const whitespaceRegex = /^\s*$/;
9
+ const preOpRegexElems = [
10
+ // Template strings
11
+ '`(?:[^`\\\\]|\\\\.)*`',
12
+ // Strings
13
+ String.raw `'(?:(?:\\')|[^'])*'`,
14
+ String.raw `"(?:(?:\\")|[^"])*"`,
15
+ // Whitespace
16
+ String.raw `\s+`,
17
+ // Booleans
18
+ String.raw `\btrue\b`,
19
+ String.raw `\bfalse\b`
20
+ ];
21
+ const postOpRegexElems = [
22
+ // Identifiers
23
+ '[a-zA-Zа-яА-Я_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\\$][a-zA-Z0-9а-яА-Я_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\\$]*',
24
+ // Numerics (without negative symbol)
25
+ String.raw `(?:(?:[0-9]*\.[0-9]+)|[0-9]+)`
26
+ ];
27
+ const minusNegatesAfter = new Set([
28
+ 'binaryOp',
29
+ 'unaryOp',
30
+ 'openParen',
31
+ 'openBracket',
32
+ 'question',
33
+ 'colon'
34
+ ]);
35
+ /**
36
+ * Lexer is a collection of stateless, statically-accessed functions for the
37
+ * lexical parsing of a Jexl string. Its responsibility is to identify the
38
+ * "parts of speech" of a Jexl expression, and tokenize and label each, but
39
+ * to do only the most minimal syntax checking; the only errors the Lexer
40
+ * should be concerned with are if it's unable to identify the utility of
41
+ * any of its tokens. Errors stemming from these tokens not being in a
42
+ * sensible configuration should be left for the Parser to handle.
43
+ * @type {{}}
44
+ */
45
+ class Lexer {
46
+ constructor(grammar) {
47
+ this._escQuoteRegexCache = new Map();
48
+ this._grammar = grammar;
49
+ }
50
+ /**
51
+ * Splits a Jexl expression string into an array of expression elements.
52
+ * @param {string} str A Jexl expression string
53
+ * @returns {Array<string>} An array of substrings defining the functional
54
+ * elements of the expression.
55
+ */
56
+ getElements(str) {
57
+ const regex = this._getSplitRegex();
58
+ return str.split(regex).filter(Boolean);
59
+ }
60
+ /**
61
+ * Converts an array of expression elements into an array of tokens. Note that
62
+ * the resulting array may not equal the element array in length, as any
63
+ * elements that consist only of whitespace get appended to the previous
64
+ * token's "raw" property. For the structure of a token object, please see
65
+ * {@link Lexer#tokenize}.
66
+ * @param {Array<string>} elements An array of Jexl expression elements to be
67
+ * converted to tokens
68
+ * @returns {Array<{type, value, raw}>} an array of token objects.
69
+ */
70
+ getTokens(elements) {
71
+ const tokens = [];
72
+ let negate = false;
73
+ for (let i = 0; i < elements.length; i++) {
74
+ if (this._isWhitespace(elements[i])) {
75
+ if (tokens.length) {
76
+ tokens[tokens.length - 1].raw += elements[i];
77
+ }
78
+ }
79
+ else if (elements[i] === '-' && this._isNegative(tokens)) {
80
+ negate = true;
81
+ }
82
+ else {
83
+ if (negate) {
84
+ elements[i] = '-' + elements[i];
85
+ negate = false;
86
+ }
87
+ tokens.push(this._createToken(elements[i]));
88
+ }
89
+ }
90
+ // Catch a - at the end of the string. Let the parser handle that issue.
91
+ if (negate) {
92
+ tokens.push(this._createToken('-'));
93
+ }
94
+ return tokens;
95
+ }
96
+ /**
97
+ * Converts a Jexl string into an array of tokens. Each token is an object
98
+ * in the following format:
99
+ *
100
+ * {
101
+ * type: <string>,
102
+ * [name]: <string>,
103
+ * value: <boolean|number|string>,
104
+ * raw: <string>
105
+ * }
106
+ *
107
+ * Type is one of the following:
108
+ *
109
+ * literal, identifier, binaryOp, unaryOp
110
+ *
111
+ * OR, if the token is a control character its type is the name of the element
112
+ * defined in the Grammar.
113
+ *
114
+ * Name appears only if the token is a control string found in
115
+ * {@link grammar#elements}, and is set to the name of the element.
116
+ *
117
+ * Value is the value of the token in the correct type (boolean or numeric as
118
+ * appropriate). Raw is the string representation of this value taken directly
119
+ * from the expression string, including any trailing spaces.
120
+ * @param {string} str The Jexl string to be tokenized
121
+ * @returns {Array<{type, value, raw}>} an array of token objects.
122
+ * @throws {Error} if the provided string contains an invalid token.
123
+ */
124
+ tokenize(str) {
125
+ const elements = this.getElements(str);
126
+ return this.getTokens(elements);
127
+ }
128
+ /**
129
+ * Creates a new token object from an element of a Jexl string. See
130
+ * {@link Lexer#tokenize} for a description of the token object.
131
+ * @param {string} element The element from which a token should be made
132
+ * @returns {{value: number|boolean|string, [name]: string, type: string,
133
+ * raw: string}} a token object describing the provided element.
134
+ * @throws {Error} if the provided string is not a valid expression element.
135
+ * @private
136
+ */
137
+ _createToken(element) {
138
+ const token = {
139
+ type: 'literal',
140
+ value: element,
141
+ raw: element
142
+ };
143
+ if (element.startsWith('`')) {
144
+ token.type = 'templateString';
145
+ token.value = this._parseTemplateString(element);
146
+ return token;
147
+ }
148
+ else if (element.startsWith('"') || element.startsWith("'")) {
149
+ token.value = this._unquote(element);
150
+ }
151
+ else if (numericRegex.exec(element)) {
152
+ token.value = parseFloat(element);
153
+ }
154
+ else if (element === 'true' || element === 'false') {
155
+ token.value = element === 'true';
156
+ }
157
+ else if (this._grammar.elements[element]) {
158
+ token.type = this._grammar.elements[element].type;
159
+ }
160
+ else if (identRegex.exec(element)) {
161
+ token.type = 'identifier';
162
+ }
163
+ else {
164
+ throw new Error(`Invalid expression token: ${element}`);
165
+ }
166
+ return token;
167
+ }
168
+ /**
169
+ * Escapes a string so that it can be treated as a string literal within a
170
+ * regular expression.
171
+ * @param {string} str The string to be escaped
172
+ * @returns {string} the RegExp-escaped string.
173
+ * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
174
+ * @private
175
+ */
176
+ _escapeRegExp(str) {
177
+ str = str.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
178
+ if (identRegex.exec(str)) {
179
+ str = String.raw `\b` + str + String.raw `\b`;
180
+ }
181
+ return str;
182
+ }
183
+ /**
184
+ * Gets a RegEx object appropriate for splitting a Jexl string into its core
185
+ * elements.
186
+ * @returns {RegExp} An element-splitting RegExp object
187
+ * @private
188
+ */
189
+ _getSplitRegex() {
190
+ if (!this._splitRegex) {
191
+ // Sort by most characters to least, then regex escape each
192
+ const elemArray = Object.keys(this._grammar.elements)
193
+ .sort((a, b) => {
194
+ return b.length - a.length;
195
+ })
196
+ .map((elem) => {
197
+ return this._escapeRegExp(elem);
198
+ });
199
+ this._splitRegex = new RegExp('(' +
200
+ [
201
+ preOpRegexElems.join('|'),
202
+ elemArray.join('|'),
203
+ postOpRegexElems.join('|')
204
+ ].join('|') +
205
+ ')');
206
+ }
207
+ return this._splitRegex;
208
+ }
209
+ /**
210
+ * Determines whether the addition of a '-' token should be interpreted as a
211
+ * negative symbol for an upcoming number, given an array of tokens already
212
+ * processed.
213
+ * @param {Array<Object>} tokens An array of tokens already processed
214
+ * @returns {boolean} true if adding a '-' should be considered a negative
215
+ * symbol; false otherwise
216
+ * @private
217
+ */
218
+ _isNegative(tokens) {
219
+ if (!tokens.length) {
220
+ return true;
221
+ }
222
+ return minusNegatesAfter.has(tokens[tokens.length - 1].type);
223
+ }
224
+ /**
225
+ * A utility function to determine if a string consists of only space
226
+ * characters.
227
+ * @param {string} str A string to be tested
228
+ * @returns {boolean} true if the string is empty or consists of only spaces;
229
+ * false otherwise.
230
+ * @private
231
+ */
232
+ _isWhitespace(str) {
233
+ return !!whitespaceRegex.exec(str);
234
+ }
235
+ /**
236
+ * Removes the beginning and trailing quotes from a string, unescapes any
237
+ * escaped quotes on its interior, and unescapes any escaped escape
238
+ * characters. Note that this function is not defensive; it assumes that the
239
+ * provided string is not empty, and that its first and last characters are
240
+ * actually quotes.
241
+ * @param {string} str A string whose first and last characters are quotes
242
+ * @returns {string} a string with the surrounding quotes stripped and escapes
243
+ * properly processed.
244
+ * @private
245
+ */
246
+ _unquote(str) {
247
+ const quote = str[0];
248
+ let escQuoteRegex = this._escQuoteRegexCache.get(quote);
249
+ if (!escQuoteRegex) {
250
+ escQuoteRegex = new RegExp('\\\\' + quote, 'g');
251
+ this._escQuoteRegexCache.set(quote, escQuoteRegex);
252
+ }
253
+ return str
254
+ .slice(1, -1)
255
+ .replace(escQuoteRegex, quote)
256
+ .replace(escEscRegex, '\\');
257
+ }
258
+ _parseTemplateString(str) {
259
+ const parts = [];
260
+ let current = 1;
261
+ let staticStart = 1;
262
+ while (current < str.length - 1) {
263
+ if (str[current] === '\\') {
264
+ current += 2;
265
+ continue;
266
+ }
267
+ if (str[current] === '$' && str[current + 1] === '{') {
268
+ if (current > staticStart) {
269
+ parts.push({
270
+ type: 'static',
271
+ value: str.slice(staticStart, current)
272
+ });
273
+ }
274
+ let braceDepth = 1;
275
+ const interpStart = current + 2;
276
+ current += 2;
277
+ while (current < str.length && braceDepth > 0) {
278
+ if (str[current] === '\\') {
279
+ current += 2;
280
+ continue;
281
+ }
282
+ if (str[current] === '{') {
283
+ braceDepth++;
284
+ }
285
+ if (str[current] === '}') {
286
+ braceDepth--;
287
+ }
288
+ current++;
289
+ }
290
+ if (braceDepth !== 0) {
291
+ throw new Error(`Unclosed interpolation in template string: ${str}`);
292
+ }
293
+ parts.push({
294
+ type: 'interpolation',
295
+ value: str.slice(interpStart, current - 1)
296
+ });
297
+ staticStart = current;
298
+ }
299
+ else {
300
+ current++;
301
+ }
302
+ }
303
+ if (current > staticStart) {
304
+ parts.push({
305
+ type: 'static',
306
+ value: str.slice(staticStart, current)
307
+ });
308
+ }
309
+ return parts;
310
+ }
311
+ _unescapeTemplateString(str) {
312
+ return str
313
+ .replaceAll('\\`', '`')
314
+ .replaceAll(String.raw `\$`, '$')
315
+ .replaceAll('\\\\', '\\');
316
+ }
317
+ }
318
+ export default Lexer;
319
+ //# sourceMappingURL=Lexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lexer.js","sourceRoot":"","sources":["../src/Lexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ declare class PromiseSync<T = unknown> {
2
+ value?: T;
3
+ error?: unknown;
4
+ constructor(fn: (resolve: (val: T) => void, reject: (error: unknown) => void) => void);
5
+ catch<TResult = never>(rejected: (error: unknown) => TResult): PromiseSync<T | TResult>;
6
+ then<TResult1 = T, TResult2 = never>(resolved: (val: T) => TResult1, rejected?: (error: unknown) => TResult2): PromiseSync<TResult1 | TResult2>;
7
+ _reject(error: unknown): void;
8
+ _resolve(val: any): void;
9
+ static all<T>(vals: (PromiseSync<T> | T)[]): PromiseSync<T[]>;
10
+ static resolve<T>(val?: T): PromiseSync<T>;
11
+ static reject(error: unknown): PromiseSync<never>;
12
+ }
13
+ export default PromiseSync;
@@ -0,0 +1,78 @@
1
+ /*
2
+ * Jexl
3
+ * Copyright 2020 Tom Shawver
4
+ */
5
+ class PromiseSync {
6
+ constructor(fn) {
7
+ fn(this._resolve.bind(this), this._reject.bind(this));
8
+ }
9
+ catch(rejected) {
10
+ if (this.error) {
11
+ try {
12
+ this._resolve(rejected(this.error));
13
+ }
14
+ catch (e) {
15
+ this._reject(e);
16
+ }
17
+ }
18
+ return this;
19
+ }
20
+ // eslint-disable-next-line unicorn/no-thenable
21
+ then(resolved, rejected) {
22
+ if (!this.error) {
23
+ try {
24
+ this._resolve(resolved(this.value));
25
+ }
26
+ catch (e) {
27
+ this._reject(e);
28
+ }
29
+ }
30
+ if (rejected) {
31
+ this.catch(rejected);
32
+ }
33
+ return this;
34
+ }
35
+ _reject(error) {
36
+ this.value = undefined;
37
+ this.error = error;
38
+ }
39
+ _resolve(val) {
40
+ if (val instanceof PromiseSync) {
41
+ if (val.error) {
42
+ this._reject(val.error);
43
+ }
44
+ else {
45
+ this._resolve(val.value);
46
+ }
47
+ }
48
+ else {
49
+ this.value = val;
50
+ this.error = undefined;
51
+ }
52
+ }
53
+ static all(vals) {
54
+ return new PromiseSync((resolve) => {
55
+ const resolved = vals.map((val) => {
56
+ while (val instanceof PromiseSync) {
57
+ if (val.error) {
58
+ if (val.error instanceof Error) {
59
+ throw val.error;
60
+ }
61
+ throw new Error(typeof val.error === 'string' ? val.error : JSON.stringify(val.error));
62
+ }
63
+ val = val.value;
64
+ }
65
+ return val;
66
+ });
67
+ resolve(resolved);
68
+ });
69
+ }
70
+ static resolve(val) {
71
+ return new PromiseSync((resolve) => { resolve(val); });
72
+ }
73
+ static reject(error) {
74
+ return new PromiseSync((_, reject) => { reject(error); });
75
+ }
76
+ }
77
+ export default PromiseSync;
78
+ //# sourceMappingURL=PromiseSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PromiseSync.js","sourceRoot":"","sources":["../src/PromiseSync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import type { AstNode } from '../types.ts';
2
+ interface Grammar {
3
+ elements: Record<string, any>;
4
+ [key: string]: any;
5
+ }
6
+ type PromiseConstructor = typeof Promise | any;
7
+ /**
8
+ * The Evaluator takes a Jexl expression tree as generated by the
9
+ * {@link Parser} and calculates its value within a given context. The
10
+ * collection of transforms, context, and a relative context to be used as the
11
+ * root for relative identifiers, are all specific to an Evaluator instance.
12
+ * When any of these things change, a new instance is required. However, a
13
+ * single instance can be used to simultaneously evaluate many different
14
+ * expressions, and does not have to be reinstantiated for each.
15
+ * @param {{}} grammar A grammar object against which to evaluate the expression
16
+ * tree
17
+ * @param {{}} [context] A map of variable keys to their values. This will be
18
+ * accessed to resolve the value of each non-relative identifier. Any
19
+ * Promise values will be passed to the expression as their resolved
20
+ * value.
21
+ * @param {{}|Array<{}|Array>} [relativeContext] A map or array to be accessed
22
+ * 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
+ */
26
+ declare class Evaluator {
27
+ _grammar: Grammar;
28
+ _context: any;
29
+ _relContext: any;
30
+ Promise: PromiseConstructor;
31
+ constructor(grammar: Grammar, context?: any, relativeContext?: any, promise?: PromiseConstructor);
32
+ /**
33
+ * Evaluates an expression tree within the configured context.
34
+ * @param {{}} ast An expression tree object
35
+ * @returns {Promise<*>} resolves with the resulting value of the expression.
36
+ */
37
+ eval(ast: AstNode): any;
38
+ /**
39
+ * Simultaneously evaluates each expression within an array, and delivers the
40
+ * response as an array with the resulting values at the same indexes as their
41
+ * originating expressions.
42
+ * @param {Array<string>} arr An array of expression strings to be evaluated
43
+ * @returns {Promise<Array<{}>>} resolves with the result array
44
+ */
45
+ evalArray(arr: AstNode[]): any;
46
+ /**
47
+ * Simultaneously evaluates each expression within a map, and delivers the
48
+ * response as a map with the same keys, but with the evaluated result for each
49
+ * as their value.
50
+ * @param {{}} map A map of expression names to expression trees to be
51
+ * evaluated
52
+ * @returns {Promise<{}>} resolves with the result map.
53
+ */
54
+ evalMap(map: Record<string, AstNode>): any;
55
+ /**
56
+ * Applies a filter expression with relative identifier elements to a subject.
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;
91
+ }
92
+ export default Evaluator;
@@ -0,0 +1,118 @@
1
+ /*
2
+ * Jexl
3
+ * Copyright 2020 Tom Shawver
4
+ */
5
+ import * as handlers from "./handlers.js";
6
+ /**
7
+ * The Evaluator takes a Jexl expression tree as generated by the
8
+ * {@link Parser} and calculates its value within a given context. The
9
+ * collection of transforms, context, and a relative context to be used as the
10
+ * root for relative identifiers, are all specific to an Evaluator instance.
11
+ * When any of these things change, a new instance is required. However, a
12
+ * single instance can be used to simultaneously evaluate many different
13
+ * expressions, and does not have to be reinstantiated for each.
14
+ * @param {{}} grammar A grammar object against which to evaluate the expression
15
+ * tree
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. Any
18
+ * Promise values will be passed to the expression as their resolved
19
+ * value.
20
+ * @param {{}|Array<{}|Array>} [relativeContext] A map or array to be accessed
21
+ * 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
+ */
25
+ class Evaluator {
26
+ constructor(grammar, context, relativeContext, promise = Promise) {
27
+ this._grammar = grammar;
28
+ this._context = context || {};
29
+ this._relContext = relativeContext || this._context;
30
+ this.Promise = promise;
31
+ }
32
+ /**
33
+ * Evaluates an expression tree within the configured context.
34
+ * @param {{}} ast An expression tree object
35
+ * @returns {Promise<*>} resolves with the resulting value of the expression.
36
+ */
37
+ eval(ast) {
38
+ return this.Promise.resolve().then(() => {
39
+ return handlers[ast.type].call(this, ast);
40
+ });
41
+ }
42
+ /**
43
+ * Simultaneously evaluates each expression within an array, and delivers the
44
+ * response as an array with the resulting values at the same indexes as their
45
+ * originating expressions.
46
+ * @param {Array<string>} arr An array of expression strings to be evaluated
47
+ * @returns {Promise<Array<{}>>} resolves with the result array
48
+ */
49
+ evalArray(arr) {
50
+ return this.Promise.all(arr.map((elem) => this.eval(elem)));
51
+ }
52
+ /**
53
+ * Simultaneously evaluates each expression within a map, and delivers the
54
+ * response as a map with the same keys, but with the evaluated result for each
55
+ * as their value.
56
+ * @param {{}} map A map of expression names to expression trees to be
57
+ * evaluated
58
+ * @returns {Promise<{}>} resolves with the result map.
59
+ */
60
+ evalMap(map) {
61
+ const entries = Object.entries(map);
62
+ const promises = entries.map(([_, ast]) => this.eval(ast));
63
+ return this.Promise.all(promises).then((vals) => Object.fromEntries(entries.map(([key], idx) => [key, vals[idx]])));
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
+ });
115
+ }
116
+ }
117
+ export default Evaluator;
118
+ //# sourceMappingURL=Evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Evaluator.js","sourceRoot":"","sources":["../../src/evaluator/Evaluator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAYzC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,SAAS;IAMb,YACE,OAAgB,EAChB,OAAa,EACb,eAAqB,EACrB,UAA8B,OAAO;QAErC,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;QACnD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,GAAY;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YACtC,OAAQ,QAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACpD,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,GAAc;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAa,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACtE,CAAC;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,GAA4B;QAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAW,EAAE,EAAE,CACrD,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,CAClE,CAAA;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,eAAe,CAAC,OAAY,EAAE,IAAa;QACzC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAChC,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,OAAO,IAAI,IAAI;gBACf,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QAEf,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAChC,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3E,CAAA;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,MAAa,EAAE,EAAE,CACvD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CACpC,CAAA;IACH,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,OAAY,EAAE,IAAa;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,EAAE;YACvC,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;YAClC,CAAC;YACD,OAAO,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAED,eAAe,SAAS,CAAA"}