fig-tree-evaluator 2.3.1 → 2.3.3

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/README.md CHANGED
@@ -4,9 +4,11 @@
4
4
 
5
5
  **FigTree Evaluator** is a module to evaluate JSON-structured expression trees.
6
6
 
7
- A typical use case would be for evaluating **configuration** files, where you need to store dynamic values or arbitrary logic without allowing users to inject executable code (perhaps in a .json file, say). For example, a [form-builder app](https://github.com/openmsupply/conforma-web-app) might need to allow complex conditional logic for form element visibility based on previous responses, or for validation beyond what is available in standard validation libraries.
7
+ A typical use case would be for evaluating **configuration** files, where you need to store dynamic values or arbitrary logic without allowing users to inject executable code (perhaps in a .json file, say). Use cases could include:
8
8
 
9
- Another example would be to configure a [decision tree](https://en.wikipedia.org/wiki/Decision_tree) to implement branching logic.
9
+ - a [form-builder app](https://github.com/openmsupply/conforma-web-app) might need to allow complex conditional logic for form element visibility based on previous responses, or for validation beyond what is available in standard validation libraries.
10
+ - configure a [decision tree](https://en.wikipedia.org/wiki/Decision_tree) to implement branching logic. (See examples in `20_match.test.ts`)
11
+ - extend [JSON Forms](https://jsonforms.io) with more complex logic and dynamic lookups: https://github.com/CarlosNZ/jsonforms-with-figtree-demo
10
12
 
11
13
  A range of built-in operators are available, from simple logic, arithmetic and string manipulation, to data fetching from local sources or remote APIs.
12
14
 
@@ -165,7 +167,7 @@ import { evaluateExpression } from 'fig-tree-evaluator'
165
167
 
166
168
  evaluateExpression(expression, [options]).then((result) => {
167
169
  // Do something with result
168
- }
170
+ })
169
171
  ```
170
172
 
171
173
  ## Operator nodes
@@ -202,13 +204,13 @@ For example, the following two representations are equivalent `conditional` oper
202
204
  }
203
205
  ```
204
206
 
205
- Most of the time named properties is preferable; however there are situations where the "children" array might be easier to deal with, or to generate from child nodes.
207
+ Most of the time named properties would be preferable; however there are occasional cases where the "children" array might be easier to deal with, or to build up from child nodes.
206
208
 
207
209
  ### Other common properties:
208
210
 
209
- In each operator node, as well as the operator-specific properties, the following two optional properties can be provided:
211
+ In each operator node, as well as the operator-specific properties, the following three optional properties can be provided:
210
212
 
211
- - `fallback`: if the operation throws an error, the `fallback` value will be returned instead. The `fallback` property can be provided at any level of the expression tree and bubbled up from where errors are caught to parent nodes.
213
+ - `fallback`: if the operation throws an error, the `fallback` value will be returned instead. The `fallback` property can be provided at any level of the expression tree and bubbled up from where errors are caught to parent nodes. *Fallbacks are strongly recommended if there is any chance of an error (e.g. a network "GET" request that doesn't yet have its parameters defined).*
212
214
  - `outputType` (or `type`): will convert the result of the current node to the specified `outputType`. Valid values are `string`, `number`, `boolean` (or `bool`), and `array`. You can experiment in the [demo app](https://carlosnz.github.io/fig-tree-evaluator/) to see the outcome of applying different `outputType` values to various results.
213
215
  - `useCache`: Overrides the global `useCache` value (from [options](#available-options)) for this node only. See [Caching/Memoization](#caching-memoization) below for more info.
214
216
 
@@ -431,7 +433,7 @@ e.g.
431
433
  ----
432
434
  ### MULTIPLY
433
435
 
434
- *Multiplcation*
436
+ *Multiplication*
435
437
 
436
438
  Aliases: `*`, `x`, `multiply`, `times`
437
439
 
@@ -634,6 +636,8 @@ e.g.
634
636
 
635
637
  `children` array: `[condition, valueIfTrue, valueIfFalse]`
636
638
 
639
+ **Note**: *For more complex branching logic, the ["match" operator](#match) can be used (it matches more than just a boolean condition)*
640
+
637
641
  ----
638
642
  ### REGEX
639
643
 
@@ -719,8 +723,10 @@ Here is the result of various values of `expression:`
719
723
  Notice the last example pulls multiple values out of an array of objects, in this case the "name". This is essentially a shorthand for:
720
724
 
721
725
  ```js
722
- const result = { operator: 'getProperty', path: 'user.enemies' }
723
- result.map((e) => e.name)
726
+ exp.evaluate(
727
+ { operator: 'getProperty', path: 'user.enemies' },
728
+ { data: { user } }
729
+ ).map((e) => e.name)
724
730
  ```
725
731
 
726
732
  The "objectProperties" operator uses [`object-property-extractor`](https://www.npmjs.com/package/object-property-extractor) internally, so please see the documentation of that package for more information.
@@ -840,7 +846,7 @@ Aliases: `split`, `arraySplit`
840
846
  - `excludeTrailing` (or `removeTrailing`, `excludeTrailingDelimiter`): (boolean, default `true`) -- if `false`, if the input string ends with the delimiter, the last member of the output array will be an empty string.
841
847
  i.e. `this, that, another,` (delimiter `","`) => `["this", "that", "another", ""]`
842
848
 
843
- The last two parameters (`timeWhiteSpace` and `excludeTrailing`) should rarely be needed.
849
+ The last two parameters (`timeWhiteSpace` and `excludeTrailing`) should *rarely* be needed to be changed from their default values.
844
850
 
845
851
  e.g.
846
852
  ```js
@@ -978,7 +984,7 @@ The required connection object is:
978
984
  }
979
985
  ```
980
986
 
981
- The following example expression uses the GraphQL connection: `{endpoint: 'https://countries.trevorblades.com/'}`
987
+ The following example expression uses the GraphQL connection (specified in constructor options): `{endpoint: 'https://countries.trevorblades.com/'}`
982
988
  ```js
983
989
  {
984
990
  operator: 'graphQL',
@@ -1121,7 +1127,7 @@ e.g.
1121
1127
 
1122
1128
  `children` array: `[key1, value1, key2, value2, ...]`
1123
1129
 
1124
- This is one of the few operators where the `children` array might actually be simpler to define than the `properties` property, depending on how deep the array elements are themselves operator nodes.
1130
+ This is one of the few cases where the `children` array might actually be simpler to define than the `properties` property, depending on how deep the array elements are themselves operator nodes.
1125
1131
 
1126
1132
  e.g.
1127
1133
  ```js
@@ -1221,7 +1227,6 @@ This expression could also be written as (with branch/case keys at the root leve
1221
1227
 
1222
1228
  The pairs of `key`/`value`s are constructed into the `branches` object, the same way the objects are built using `children` in the ["buildObject"](#build_object) operator.
1223
1229
 
1224
-
1225
1230
  For an example of a complex decision tree implementation, which includes [aliases](#alias-nodes), [fallbacks](#other-common-properties) and a range of operators, see the "match" test case file (`20_match.test.ts`).
1226
1231
 
1227
1232
  ----
@@ -1298,7 +1303,7 @@ Here is the result of various expressions:
1298
1303
  },
1299
1304
  ],
1300
1305
  }
1301
- // => "THE CURRENT YEAR IS: 2022"
1306
+ // => "THE CURRENT YEAR IS: 2023"
1302
1307
  ```
1303
1308
 
1304
1309
  `children` array: `[functionPath, ...args]`
@@ -1314,7 +1319,7 @@ e.g.
1314
1319
 
1315
1320
  ## Alias Nodes
1316
1321
 
1317
- If you have a node that is used more than once in a complex expression, it's possible to just evaluate the repeated node once, and refer to it throughout using an "alias" reference. This allows for a simpler expression (reduces duplication) as well as a performance improvement, since the aliased node is only evaluated once, providing a simple [memoization](https://en.wikipedia.org/wiki/Memoization) mechanism.
1322
+ If you have a node that is used more than once in a complex expression, it's possible to just evaluate the repeated node once, and refer to it throughout using an "alias" reference. This allows for a simpler expression (reduces code duplication) as well as a performance improvement, since the aliased node is only evaluated once, providing a simple [memoization](https://en.wikipedia.org/wiki/Memoization) mechanism. (See also [Caching/Memoization](#caching-memoization))
1318
1323
 
1319
1324
  For example, if you have the expression:
1320
1325
  ```js
@@ -1385,7 +1390,7 @@ Like all expression nodes, alias nodes can themselves contain complex expression
1385
1390
 
1386
1391
  ## Caching (Memoization)
1387
1392
 
1388
- FigTree Evaluator has basic memoization functionality for certain nodes to speed up re-evaluation of previously evaluated nodes. There is a single cache store per FigTree instance which persists for the lifetime of the instance. By default, it remembers the last 50 results, but this can be modified using the `maxCacheSize` option.
1393
+ FigTree Evaluator has basic [memoization](https://en.wikipedia.org/wiki/Memoization) functionality for certain nodes to speed up re-evaluation when the input parameters haven't changed. There is a single cache store per FigTree instance which persists for the lifetime of the instance. By default, it remembers the last 50 results, but this can be modified using the `maxCacheSize` option.
1389
1394
 
1390
1395
  Currently, caching is only implemented for the following operators, since they perform requests to external resources, which are inherently slow:
1391
1396
 
@@ -1395,6 +1400,10 @@ Currently, caching is only implemented for the following operators, since they p
1395
1400
  - GRAPH_QL (`useCache` default: `true`)
1396
1401
  - CUSTOM_FUNCTIONS (`useCache` default: `false`)
1397
1402
 
1403
+ This is different to the memoization provided by [Alias Nodes](#alias-nodes):
1404
+ - Alias nodes are still evaluated once for every evaluation -- they're more for re-use *within* a complex expression.
1405
+ - Cached nodes will persist *between* different evaluations as long as the input values are the same as a previously evaluated node.
1406
+
1398
1407
  ## More examples
1399
1408
 
1400
1409
  More examples, included large, complex expressions can be found within the test suites in the [repository](https://github.com/CarlosNZ/fig-tree-evaluator).
@@ -1427,7 +1436,7 @@ Please open an issue: https://github.com/CarlosNZ/fig-tree-evaluator/issues
1427
1436
 
1428
1437
  ## Changelog
1429
1438
 
1430
- - **v2.3.1**: Bug fix: alias nodes not working with `evaluateFullObject` (#72)
1439
+ - **v2.3.2**: Bug fix: alias nodes not working with `evaluateFullObject` (#72)
1431
1440
  - **v2.3.0**: Implement [caching/memoization](#caching-memoization) (#68)
1432
1441
  - **v2.2.3**: Change option `objects` name to `data` (but keep backward compatibility) (#66)
1433
1442
  - **v2.2.2**: Option to evaluate whole object if operator nodes are deep within it (#64)
package/build/cache.js CHANGED
@@ -59,7 +59,6 @@ var FigTreeCache = (function () {
59
59
  if (key in this.store) {
60
60
  this.queue = this.queue.filter(function (val) { return val !== key; });
61
61
  this.queue.unshift(key);
62
- console.log('Using cached result:', this.store[key]);
63
62
  return [2, this.store[key]];
64
63
  }
65
64
  return [4, action.apply(void 0, args)];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fig-tree-evaluator",
3
- "version": "2.3.1",
3
+ "version": "2.3.3",
4
4
  "description": "Module to evaluate JSON-structured expression trees",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",