@briza/illogical 2.0.2 → 2.2.0
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/lib/illogical.cjs +3324 -158
- package/lib/illogical.esm.js +3324 -158
- package/package.json +23 -4
- package/readme.md +5 -0
- package/types/bytecode/compiler.d.ts +29 -0
- package/types/bytecode/evaluable.d.ts +14 -0
- package/types/bytecode/get-bytecode.d.ts +1 -0
- package/types/bytecode/interpreter.d.ts +10 -0
- package/types/bytecode/opcodes.d.ts +51 -0
- package/types/bytecode/operateWithExpectedDecimals.d.ts +1 -0
- package/types/bytecode/refs.d.ts +73 -0
- package/types/bytecode/simplifier.d.ts +16 -0
- package/types/common/type-check.d.ts +7 -2
- package/types/common/util.d.ts +6 -0
- package/types/expression/arithmetic/dateArithmeticTypeCheck.d.ts +2 -0
- package/types/expression/arithmetic/index.d.ts +2 -0
- package/types/expression/arithmetic/mutateDateWithDuration.d.ts +2 -0
- package/types/index.d.ts +5 -1
- package/types/parser/options.d.ts +12 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@briza/illogical",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "A micro conditional javascript engine used to parse the raw logical and comparison expressions, evaluate the expression in the given data context, and provide access to a text form of the given expressions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/illogical.cjs",
|
|
@@ -32,10 +32,29 @@
|
|
|
32
32
|
"lint:fix": "eslint --max-warnings 0 \"src/**/*.{ts,js}\" --fix",
|
|
33
33
|
"prepublishOnly": "npm run test && npm run build",
|
|
34
34
|
"check-licenses": "license-checker --summary --excludePrivatePackages --onlyAllow \"MIT;MIT OR X11;Apache-2.0;ISC;BSD-3-Clause;BSD-2-Clause;CC-BY-4.0;Public Domain;BSD;CC-BY-3.0;CC0-1.0;Python-2.0;BlueOak-1.0.0;Unlicense\"",
|
|
35
|
-
"bench
|
|
36
|
-
"bench:sample:oop:
|
|
35
|
+
"bench": "npm run build && node --import tsx src/benchmark/evaluate.ts --cases conditions/sample-conditions --out benchmark/results-sample-evaluate-oop.json && node --import tsx src/benchmark/evaluate.ts --cases conditions/sample-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-sample-evaluate-bytecode.json && node --import tsx src/benchmark/evaluate.ts --cases conditions/synthetic-conditions --out benchmark/results-synthetic-evaluate-oop.json && node --import tsx src/benchmark/evaluate.ts --cases conditions/synthetic-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-synthetic-evaluate-bytecode.json && node --import tsx src/benchmark/simplify.ts --cases conditions/sample-conditions --out benchmark/results-sample-simplify-oop.json && node --import tsx src/benchmark/simplify.ts --cases conditions/sample-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-sample-simplify-bytecode.json && node --import tsx src/benchmark/simplify.ts --cases conditions/synthetic-conditions --out benchmark/results-synthetic-simplify-oop.json && node --import tsx src/benchmark/simplify.ts --cases conditions/synthetic-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-synthetic-simplify-bytecode.json && node --import tsx src/benchmark/report.ts benchmark/results-sample-evaluate-oop.json benchmark/results-sample-evaluate-bytecode.json --op evaluate --out benchmark/report-sample-evaluate.md && node --import tsx src/benchmark/report.ts benchmark/results-synthetic-evaluate-oop.json benchmark/results-synthetic-evaluate-bytecode.json --op evaluate --out benchmark/report-synthetic-evaluate.md && node --import tsx src/benchmark/report.ts benchmark/results-sample-simplify-oop.json benchmark/results-sample-simplify-bytecode.json --op simplify --out benchmark/report-sample-simplify.md && node --import tsx src/benchmark/report.ts benchmark/results-synthetic-simplify-oop.json benchmark/results-synthetic-simplify-bytecode.json --op simplify --out benchmark/report-synthetic-simplify.md",
|
|
36
|
+
"bench:sample:oop:evaluate": "npm run build && node --import tsx src/benchmark/evaluate.ts --cases conditions/sample-conditions --out benchmark/results-sample-evaluate-oop.json",
|
|
37
|
+
"bench:sample:oop:simplify": "npm run build && node --import tsx src/benchmark/simplify.ts --cases conditions/sample-conditions --out benchmark/results-sample-simplify-oop.json",
|
|
37
38
|
"bench:synthetic:oop:evaluate": "npm run build && node --import tsx src/benchmark/evaluate.ts --cases conditions/synthetic-conditions --out benchmark/results-synthetic-evaluate-oop.json",
|
|
38
|
-
"bench:synthetic:oop:simplify": "npm run build && node --import tsx src/benchmark/simplify.ts --cases conditions/synthetic-conditions --out benchmark/results-synthetic-simplify-oop.json"
|
|
39
|
+
"bench:synthetic:oop:simplify": "npm run build && node --import tsx src/benchmark/simplify.ts --cases conditions/synthetic-conditions --out benchmark/results-synthetic-simplify-oop.json",
|
|
40
|
+
"bench:sample:bytecode:evaluate": "npm run build && node --import tsx src/benchmark/evaluate.ts --cases conditions/sample-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-sample-evaluate-bytecode.json",
|
|
41
|
+
"bench:sample:bytecode:simplify": "npm run build && node --import tsx src/benchmark/simplify.ts --cases conditions/sample-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-sample-simplify-bytecode.json",
|
|
42
|
+
"bench:synthetic:bytecode:evaluate": "npm run build && node --import tsx src/benchmark/evaluate.ts --cases conditions/synthetic-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-synthetic-evaluate-bytecode.json",
|
|
43
|
+
"bench:synthetic:bytecode:simplify": "npm run build && node --import tsx src/benchmark/simplify.ts --cases conditions/synthetic-conditions --options '{\"evaluator\":\"bytecode\"}' --out benchmark/results-synthetic-simplify-bytecode.json",
|
|
44
|
+
"bench:sample:compare:evaluate": "node --import tsx src/benchmark/compare.ts benchmark/results-sample-evaluate-oop.json benchmark/results-sample-evaluate-bytecode.json",
|
|
45
|
+
"bench:synthetic:compare:evaluate": "node --import tsx src/benchmark/compare.ts benchmark/results-synthetic-evaluate-oop.json benchmark/results-synthetic-evaluate-bytecode.json",
|
|
46
|
+
"bench:sample:compare:simplify": "node --import tsx src/benchmark/compare.ts benchmark/results-sample-simplify-oop.json benchmark/results-sample-simplify-bytecode.json",
|
|
47
|
+
"bench:synthetic:compare:simplify": "node --import tsx src/benchmark/compare.ts benchmark/results-synthetic-simplify-oop.json benchmark/results-synthetic-simplify-bytecode.json",
|
|
48
|
+
"bench:sample:report:evaluate": "node --import tsx src/benchmark/report.ts benchmark/results-sample-evaluate-oop.json benchmark/results-sample-evaluate-bytecode.json --op evaluate --out benchmark/report-sample-evaluate.md",
|
|
49
|
+
"bench:synthetic:report:evaluate": "node --import tsx src/benchmark/report.ts benchmark/results-synthetic-evaluate-oop.json benchmark/results-synthetic-evaluate-bytecode.json --op evaluate --out benchmark/report-synthetic-evaluate.md",
|
|
50
|
+
"bench:sample:report:full:evaluate": "node --import tsx src/benchmark/report.ts benchmark/results-sample-evaluate-oop.json benchmark/results-sample-evaluate-bytecode.json --op evaluate --full --out benchmark/report-sample-evaluate-full.md",
|
|
51
|
+
"bench:synthetic:report:full:evaluate": "node --import tsx src/benchmark/report.ts benchmark/results-synthetic-evaluate-oop.json benchmark/results-synthetic-evaluate-bytecode.json --op evaluate --full --out benchmark/report-synthetic-evaluate-full.md",
|
|
52
|
+
"bench:sample:report:simplify": "node --import tsx src/benchmark/report.ts benchmark/results-sample-simplify-oop.json benchmark/results-sample-simplify-bytecode.json --op simplify --out benchmark/report-sample-simplify.md",
|
|
53
|
+
"bench:synthetic:report:simplify": "node --import tsx src/benchmark/report.ts benchmark/results-synthetic-simplify-oop.json benchmark/results-synthetic-simplify-bytecode.json --op simplify --out benchmark/report-synthetic-simplify.md",
|
|
54
|
+
"bench:sample:report:full:simplify": "node --import tsx src/benchmark/report.ts benchmark/results-sample-simplify-oop.json benchmark/results-sample-simplify-bytecode.json --op simplify --full --out benchmark/report-sample-simplify-full.md",
|
|
55
|
+
"bench:synthetic:report:full:simplify": "node --import tsx src/benchmark/report.ts benchmark/results-synthetic-simplify-oop.json benchmark/results-synthetic-simplify-bytecode.json --op simplify --full --out benchmark/report-synthetic-simplify-full.md",
|
|
56
|
+
"get-bytecode": "node --import tsx src/bytecode/get-bytecode.ts",
|
|
57
|
+
"debug-bytecode": "node --import tsx src/tools/debugger.ts"
|
|
39
58
|
},
|
|
40
59
|
"repository": {
|
|
41
60
|
"type": "git",
|
package/readme.md
CHANGED
|
@@ -87,6 +87,11 @@ Customize the engine and the documentation:
|
|
|
87
87
|
- [Engine Options](./specs/engine.md)
|
|
88
88
|
- [Code Documentation](https://briza-insurance.github.io/illogical/index.html)
|
|
89
89
|
|
|
90
|
+
Bytecode evaluation and debugging tools:
|
|
91
|
+
|
|
92
|
+
- [Bytecode Evaluator](./specs/bytecode-evaluator.md)
|
|
93
|
+
- [Debugger Tools](./specs/debugger-tools.md)
|
|
94
|
+
|
|
90
95
|
## 📖 Changelog
|
|
91
96
|
|
|
92
97
|
See [changelog.md](./changelog.md).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bytecode compiler.
|
|
3
|
+
*
|
|
4
|
+
* Transforms a raw ExpressionInput (plain array) into a flat Bytecode array
|
|
5
|
+
* that the interpreter can execute. This runs once per unique expression;
|
|
6
|
+
* the result should be cached and reused across evaluate() calls.
|
|
7
|
+
*/
|
|
8
|
+
import { Result } from '../common/evaluable.js';
|
|
9
|
+
import { ArrayInput, ExpressionInput, Input } from '../parser/index.js';
|
|
10
|
+
import { Options } from '../parser/options.js';
|
|
11
|
+
import { CompactRef } from './refs.js';
|
|
12
|
+
export type Bytecode = (number | Result)[];
|
|
13
|
+
export interface CompiledExpression {
|
|
14
|
+
bytecode: Bytecode;
|
|
15
|
+
refs: CompactRef[];
|
|
16
|
+
numLocals: number;
|
|
17
|
+
consts: ArrayInput[];
|
|
18
|
+
opNames: Record<number, string>;
|
|
19
|
+
refKeys: string[];
|
|
20
|
+
refRawKeys: string[];
|
|
21
|
+
overlapRefsResiduals: Array<[number, Input[]]>;
|
|
22
|
+
directionMap: Array<[number, 0 | 1]>;
|
|
23
|
+
refFirstCtxKeys: (string | undefined)[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Compile a raw ExpressionInput into bytecode.
|
|
27
|
+
* The result should be cached and reused across evaluate() calls.
|
|
28
|
+
*/
|
|
29
|
+
export declare function compile(raw: ExpressionInput, opts: Options): CompiledExpression;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context, Evaluable, EvaluableType, Result } from '../common/evaluable.js';
|
|
2
|
+
import { Input } from '../parser/index.js';
|
|
3
|
+
import { Options } from '../parser/options.js';
|
|
4
|
+
import { CompiledExpression } from './compiler.js';
|
|
5
|
+
export declare class BytecodeEvaluable implements Evaluable {
|
|
6
|
+
private readonly compiled;
|
|
7
|
+
private readonly delegate;
|
|
8
|
+
readonly type = EvaluableType.Expression;
|
|
9
|
+
constructor(compiled: CompiledExpression, delegate: Evaluable);
|
|
10
|
+
evaluate(ctx: Context): Result;
|
|
11
|
+
simplify(ctx: Context, strictKeys?: string[] | Set<string>, optionalKeys?: string[] | Set<string>): Result | Input;
|
|
12
|
+
serialize(options: Options): Input;
|
|
13
|
+
toString(): string;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bytecode interpreter.
|
|
3
|
+
*
|
|
4
|
+
* Executes a compiled bytecode array against a context object.
|
|
5
|
+
* Zero allocations in the hot path: uses a pre-allocated stack
|
|
6
|
+
* and operates on the flat bytecode array directly.
|
|
7
|
+
*/
|
|
8
|
+
import { Context, Result } from '../common/evaluable.js';
|
|
9
|
+
import { CompiledExpression } from './compiler.js';
|
|
10
|
+
export declare function interpret(compiled: CompiledExpression, ctx: Context): Result;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bytecode opcodes for the illogical expression interpreter.
|
|
3
|
+
*
|
|
4
|
+
* Each opcode is a small integer. Some opcodes consume the next element(s)
|
|
5
|
+
* in the bytecode array as operand data (e.g. OP_PUSH_VALUE reads the next
|
|
6
|
+
* element as the literal value to push).
|
|
7
|
+
*/
|
|
8
|
+
export declare const OP_PUSH_VALUE = 1;
|
|
9
|
+
export declare const OP_PUSH_REF = 2;
|
|
10
|
+
export declare const OP_PUSH_REF_KEY = 6;
|
|
11
|
+
export declare const OP_PUSH_REF_KEYS = 7;
|
|
12
|
+
export declare const OP_PUSH_REF_TOKENS = 8;
|
|
13
|
+
export declare const OP_PUSH_REF_DYNAMIC = 9;
|
|
14
|
+
export declare const OP_MAKE_COLLECTION = 3;
|
|
15
|
+
export declare const OP_PUSH_CONST = 4;
|
|
16
|
+
export declare const OP_OVERLAP_CONST = 5;
|
|
17
|
+
export declare const OP_EQ = 10;
|
|
18
|
+
export declare const OP_NE = 11;
|
|
19
|
+
export declare const OP_GT = 12;
|
|
20
|
+
export declare const OP_GE = 13;
|
|
21
|
+
export declare const OP_LT = 14;
|
|
22
|
+
export declare const OP_LE = 15;
|
|
23
|
+
export declare const OP_IN = 16;
|
|
24
|
+
export declare const OP_NOT_IN = 17;
|
|
25
|
+
export declare const OP_IN_COLLECTION = 45;
|
|
26
|
+
export declare const OP_NOT_IN_COLLECTION = 46;
|
|
27
|
+
export declare const OP_IN_CONST = 49;
|
|
28
|
+
export declare const OP_NOT_IN_CONST = 50;
|
|
29
|
+
export declare const OP_OVERLAP_SCAN_REFS_CONST = 51;
|
|
30
|
+
export declare const OP_OR_AND_IN_CONST_2 = 52;
|
|
31
|
+
export declare const OP_PREFIX = 18;
|
|
32
|
+
export declare const OP_SUFFIX = 19;
|
|
33
|
+
export declare const OP_OVERLAP = 20;
|
|
34
|
+
export declare const OP_PRESENT = 21;
|
|
35
|
+
export declare const OP_UNDEFINED = 22;
|
|
36
|
+
export declare const OP_SUM = 30;
|
|
37
|
+
export declare const OP_SUBTRACT = 31;
|
|
38
|
+
export declare const OP_MULTIPLY = 32;
|
|
39
|
+
export declare const OP_DIVIDE = 33;
|
|
40
|
+
export declare const OP_STORE_LOCAL = 47;
|
|
41
|
+
export declare const OP_LOAD_LOCAL = 48;
|
|
42
|
+
export declare const OP_NOT = 40;
|
|
43
|
+
export declare const OP_JUMP_IF_FALSE = 41;
|
|
44
|
+
export declare const OP_JUMP_IF_TRUE = 42;
|
|
45
|
+
export declare const OP_POP = 43;
|
|
46
|
+
export declare const OP_XOR = 44;
|
|
47
|
+
export declare const OP_AND = 53;
|
|
48
|
+
export declare const OP_OR = 54;
|
|
49
|
+
export declare const OP_NOR = 55;
|
|
50
|
+
export declare const OP_IN_SCAN_REFS_CONST = 56;
|
|
51
|
+
export declare const OP_NOT_IN_SCAN_REFS_CONST = 57;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const operateWithExpectedDecimals: (operation: "sum" | "subtract" | "multiply") => (first: number, second: number) => number;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference path descriptors for the bytecode compiler and interpreter.
|
|
3
|
+
*
|
|
4
|
+
* CompactRef is the single runtime type stored in CompiledExpression.refs.
|
|
5
|
+
* The compiler picks the right opcode per ref kind so the interpreter
|
|
6
|
+
* dispatches to a dedicated handler with no secondary branching.
|
|
7
|
+
*
|
|
8
|
+
* string — OP_PUSH_REF_KEY — ctx[key]
|
|
9
|
+
* string[] — OP_PUSH_REF_KEYS — inline multi-key walk
|
|
10
|
+
* CompactRefFull (tokens) — OP_PUSH_REF_TOKENS — token walk + optional cast
|
|
11
|
+
* CompactRefFull (dynamic) — OP_PUSH_REF_DYNAMIC — runtime {placeholder} substitution
|
|
12
|
+
*/
|
|
13
|
+
import { Context, Result } from '../common/evaluable.js';
|
|
14
|
+
import { DataType } from '../operand/reference.js';
|
|
15
|
+
export type PathToken = {
|
|
16
|
+
kind: 'key';
|
|
17
|
+
value: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'index';
|
|
20
|
+
value: number;
|
|
21
|
+
};
|
|
22
|
+
/** Full compact form for refs that don't fit the short string/string[] forms. */
|
|
23
|
+
export interface CompactRefFull {
|
|
24
|
+
/** Raw key string for dynamic refs with {placeholder} substitution. */
|
|
25
|
+
k?: string;
|
|
26
|
+
/** True for dynamic refs. */
|
|
27
|
+
d?: true;
|
|
28
|
+
/** DataType cast, e.g. DataType.Number. */
|
|
29
|
+
t?: DataType;
|
|
30
|
+
/** Token list for paths containing array indexes or deep static paths. */
|
|
31
|
+
tokens?: PathToken[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Runtime ref representation stored in CompiledExpression.refs:
|
|
35
|
+
* - `string` → single plain-key (most common)
|
|
36
|
+
* - `string[]` → multi-key inline path
|
|
37
|
+
* - `CompactRefFull` → token-based or dynamic
|
|
38
|
+
*/
|
|
39
|
+
export type CompactRef = string | string[] | CompactRefFull;
|
|
40
|
+
/**
|
|
41
|
+
* Build a CompactRef from a raw reference key string (without the $ prefix).
|
|
42
|
+
* Called once at compile time; the result is stored in CompiledExpression.refs.
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildCompactRef(rawKey: string): CompactRef;
|
|
45
|
+
/** Type-safe property access on an object narrowed from `unknown`. */
|
|
46
|
+
export declare function propAt(obj: object, key: string): Result;
|
|
47
|
+
/** Narrow a CompactRef to its string form (OP_PUSH_REF_KEY). Throws on mismatch. */
|
|
48
|
+
export declare function asKeyRef(ref: CompactRef): string;
|
|
49
|
+
/** Narrow a CompactRef to its string[] form (OP_PUSH_REF_KEYS). Throws on mismatch. */
|
|
50
|
+
export declare function asKeysRef(ref: CompactRef): string[];
|
|
51
|
+
/** Narrow a CompactRef to CompactRefFull (OP_PUSH_REF_TOKENS / OP_PUSH_REF_DYNAMIC). Throws on mismatch. */
|
|
52
|
+
export declare function asFullRef(ref: CompactRef): CompactRefFull;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve a multi-key inline path (string[]) against a context.
|
|
55
|
+
* Used by OP_PUSH_REF_KEYS and OP_PUSH_REF_DYNAMIC (after substitution).
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveKeys(ks: string[], ctx: Context): Result;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a token-based path against a context.
|
|
60
|
+
* Used by OP_PUSH_REF_TOKENS.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveTokens(tokens: PathToken[], dataType: DataType | undefined, ctx: Context): Result;
|
|
63
|
+
/**
|
|
64
|
+
* Resolve a dynamic ref (with {placeholder} substitution) against a context.
|
|
65
|
+
* Used by OP_PUSH_REF_DYNAMIC.
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolveDynamic(key: string, dataType: DataType | undefined, ctx: Context): Result;
|
|
68
|
+
/**
|
|
69
|
+
* Resolve any CompactRef against a context.
|
|
70
|
+
* Used in ops that embed ref indices but weren't split by kind
|
|
71
|
+
* (OP_OVERLAP_SCAN_REFS_CONST, OP_OR_AND_IN_CONST_2).
|
|
72
|
+
*/
|
|
73
|
+
export declare function resolveCompactRef(ref: CompactRef, ctx: Context): Result;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bytecode simplify interpreter.
|
|
3
|
+
*
|
|
4
|
+
* Runs the same bytecode as the evaluate interpreter but supports partial
|
|
5
|
+
* evaluation. Stack slots hold either a Result (fully resolved) or an Input
|
|
6
|
+
* fragment (residual — a ref string or a sub-expression array). When an
|
|
7
|
+
* operator receives any residual operand it reconstructs the sub-expression
|
|
8
|
+
* as an Input array instead of computing a value.
|
|
9
|
+
*
|
|
10
|
+
* Short-circuit logic still applies: AND with a false short-circuits even if
|
|
11
|
+
* other operands are unknown; OR with a true short-circuits likewise.
|
|
12
|
+
*/
|
|
13
|
+
import { Context } from '../common/evaluable.js';
|
|
14
|
+
import { Input } from '../parser/index.js';
|
|
15
|
+
import { CompiledExpression } from './compiler.js';
|
|
16
|
+
export declare function interpretSimplify(compiled: CompiledExpression, ctx: Context, strictKeys?: string[] | Set<string>, optionalKeys?: string[] | Set<string>): Input;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { Operand } from '../operand/index.js';
|
|
2
|
+
import { Reference } from '../operand/reference.js';
|
|
3
|
+
import { Value } from '../operand/value.js';
|
|
1
4
|
import { Evaluable, Result } from './evaluable.js';
|
|
2
5
|
/**
|
|
3
6
|
* Is number predicate.
|
|
4
7
|
* @param value Tested value.
|
|
5
8
|
*/
|
|
6
|
-
export declare function isNumber(value:
|
|
9
|
+
export declare function isNumber(value: unknown): value is number;
|
|
7
10
|
/**
|
|
8
11
|
* Is number predicate.
|
|
9
12
|
* @param value Tested value.
|
|
@@ -13,7 +16,7 @@ export declare function isInfinite(value: Result): value is typeof Infinity;
|
|
|
13
16
|
* Is string type predicate.
|
|
14
17
|
* @param value Tested value.
|
|
15
18
|
*/
|
|
16
|
-
export declare function isString(value:
|
|
19
|
+
export declare function isString(value: unknown): value is string;
|
|
17
20
|
/**
|
|
18
21
|
* Is Object
|
|
19
22
|
* @param value tested value result of the test
|
|
@@ -45,3 +48,5 @@ export declare function areAllResults(values: (Result | Evaluable)[]): values is
|
|
|
45
48
|
export declare function areAllNumbers(results: Result[]): results is number[];
|
|
46
49
|
export declare function isUndefined(value: unknown): value is undefined;
|
|
47
50
|
export declare function isNull(value: unknown): value is null;
|
|
51
|
+
export declare function isReference(operand: Operand): operand is Reference;
|
|
52
|
+
export declare function isValue(operand: Operand): operand is Value;
|
package/types/common/util.d.ts
CHANGED
|
@@ -14,3 +14,9 @@ export declare const toString: (value: Result) => string | undefined;
|
|
|
14
14
|
* @param value value to be converted to number
|
|
15
15
|
*/
|
|
16
16
|
export declare const toDateNumber: (value: Result) => number;
|
|
17
|
+
export declare const formatDateNumber: (dateNumber: number) => string;
|
|
18
|
+
export type DateDuration = {
|
|
19
|
+
amount: number;
|
|
20
|
+
unit: 'd' | 'm' | 'y';
|
|
21
|
+
};
|
|
22
|
+
export declare const toDateDuration: (value: Result) => DateDuration | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Context, Evaluable, EvaluableType, Result, SimplifyArgs } from '../../common/evaluable.js';
|
|
2
|
+
import { DateDuration } from '../../common/util.js';
|
|
2
3
|
import { Operand } from '../../operand/index.js';
|
|
3
4
|
import { ExpressionInput } from '../../parser/index.js';
|
|
4
5
|
import { Options } from '../../parser/options.js';
|
|
@@ -27,6 +28,7 @@ export declare abstract class Arithmetic implements Evaluable {
|
|
|
27
28
|
* array of numbers
|
|
28
29
|
*/
|
|
29
30
|
protected getResultValues(results: Result[]): number[] | false;
|
|
31
|
+
protected getDateCalculationResults(results: Result[]): [number, ...DateDuration[]] | false;
|
|
30
32
|
/**
|
|
31
33
|
* Performs the arithmetic operation on the operands evaluated values.
|
|
32
34
|
* @param {Result[]} results Operand result values.
|
package/types/index.d.ts
CHANGED
|
@@ -29,18 +29,22 @@ import { OPERATOR as OPERATOR_XOR } from './expression/logical/xor.js';
|
|
|
29
29
|
import { ExpressionInput, Input } from './parser/index.js';
|
|
30
30
|
import { Options } from './parser/options.js';
|
|
31
31
|
export { defaultOptions } from './parser/options.js';
|
|
32
|
+
export type { EvaluatorMode } from './parser/options.js';
|
|
32
33
|
export { isEvaluable, OPERATOR_EQ, OPERATOR_NE, OPERATOR_GT, OPERATOR_GE, OPERATOR_LT, OPERATOR_LE, OPERATOR_IN, OPERATOR_NOT_IN, OPERATOR_PREFIX, OPERATOR_SUFFIX, OPERATOR_OVERLAP, OPERATOR_UNDEFINED, OPERATOR_PRESENT, OPERATOR_AND, OPERATOR_OR, OPERATOR_NOR, OPERATOR_XOR, OPERATOR_NOT, OPERATOR_DIVIDE, OPERATOR_MULTIPLY, OPERATOR_SUBTRACT, OPERATOR_SUM, };
|
|
33
|
-
export type { Context, Evaluable, ExpressionInput };
|
|
34
|
+
export type { Context, Evaluable, ExpressionInput, Input };
|
|
34
35
|
/**
|
|
35
36
|
* Condition engine
|
|
36
37
|
*/
|
|
37
38
|
declare class Engine {
|
|
38
39
|
private readonly parser;
|
|
40
|
+
private readonly evaluator;
|
|
41
|
+
private readonly bytecodeCache;
|
|
39
42
|
/**
|
|
40
43
|
* @constructor
|
|
41
44
|
* @param {Options?} options Parser options.
|
|
42
45
|
*/
|
|
43
46
|
constructor(options?: Partial<Options>);
|
|
47
|
+
private getCompiled;
|
|
44
48
|
/**
|
|
45
49
|
* Evaluate the expression.
|
|
46
50
|
* @param {ExpressionInput} exp Raw expression.
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export type optionValue = ((operand: string) => string | boolean) | Map<symbol, string>;
|
|
2
|
+
/**
|
|
3
|
+
* Engine evaluator mode.
|
|
4
|
+
* - `'oop'` (default): evaluates expressions using the classic OOP evaluable tree.
|
|
5
|
+
* - `'bytecode'`: compiles expressions to bytecode and interprets them.
|
|
6
|
+
*/
|
|
7
|
+
export type EvaluatorMode = 'oop' | 'bytecode';
|
|
2
8
|
export interface Options {
|
|
3
9
|
/**
|
|
4
10
|
* A function used to determine if the operand is a reference type,
|
|
@@ -35,7 +41,11 @@ export interface Options {
|
|
|
35
41
|
* is the key used to represent the given operator in the raw expression.
|
|
36
42
|
*/
|
|
37
43
|
operatorMapping: Map<symbol, string>;
|
|
38
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Evaluator mode used by the engine.
|
|
46
|
+
* Defaults to `'oop'` when not specified.
|
|
47
|
+
*/
|
|
48
|
+
evaluator?: EvaluatorMode;
|
|
39
49
|
}
|
|
40
50
|
/**
|
|
41
51
|
* Default reference predicate.
|
|
@@ -45,7 +55,7 @@ export interface Options {
|
|
|
45
55
|
* @param {string} key
|
|
46
56
|
* @return {boolean}
|
|
47
57
|
*/
|
|
48
|
-
export declare function defaultReferencePredicate(key:
|
|
58
|
+
export declare function defaultReferencePredicate(key: unknown): boolean;
|
|
49
59
|
/**
|
|
50
60
|
* Default reference transform.
|
|
51
61
|
* It removes the "$" symbol at the begging of the operand name.
|