@rs-x/expression-parser 0.4.10 → 0.4.12
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/dist/index.d.ts +166 -125
- package/dist/index.js +1107 -908
- package/package.json +3 -3
- package/readme.md +2241 -1711
package/readme.md
CHANGED
|
@@ -12,114 +12,124 @@ This parser forms the core of the **data-binding implementation** for the SPA fr
|
|
|
12
12
|
|
|
13
13
|
### Examples
|
|
14
14
|
|
|
15
|
-
- **Expression with a promise** —
|
|
16
|
-
- **Expression with an observable** -
|
|
15
|
+
- **Expression with a promise** — `promise + 2` (where `promise` resolves to a number)
|
|
16
|
+
- **Expression with an observable** - `observable + 2` (where `observable` emits a number)
|
|
17
17
|
- **Expression referencing nested async data**
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export const run = (async () => {
|
|
32
|
-
const expressionContext = {
|
|
33
|
-
a: {
|
|
34
|
-
b: Promise.resolve({
|
|
35
|
-
c: Promise.resolve({
|
|
36
|
-
d: 20
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
}
|
|
40
|
-
};
|
|
19
|
+
```ts
|
|
20
|
+
import {
|
|
21
|
+
emptyFunction,
|
|
22
|
+
InjectionContainer,
|
|
23
|
+
printValue,
|
|
24
|
+
WaitForEvent,
|
|
25
|
+
} from '@rs-x/core';
|
|
26
|
+
import {
|
|
27
|
+
IExpressionFactory,
|
|
28
|
+
RsXExpressionParserInjectionTokens,
|
|
29
|
+
RsXExpressionParserModule,
|
|
30
|
+
} from '@rs-x/expression-parser';
|
|
41
31
|
|
|
42
|
-
|
|
32
|
+
// Load the expression parser module into the injection container
|
|
33
|
+
InjectionContainer.load(RsXExpressionParserModule);
|
|
34
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
35
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
36
|
+
);
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
export const run = (async () => {
|
|
39
|
+
const expressionContext = {
|
|
40
|
+
a: {
|
|
41
|
+
b: Promise.resolve({
|
|
42
|
+
c: Promise.resolve({
|
|
43
|
+
d: 20,
|
|
44
|
+
}),
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
expression.changed.subscribe((change) => {
|
|
50
|
-
printValue(change.value);
|
|
51
|
-
});
|
|
49
|
+
const expression = expressionFactory.create(expressionContext, `a.b.c.d`);
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
try {
|
|
52
|
+
// Wait until the expression has been resolved (has a value)
|
|
53
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
54
|
+
|
|
55
|
+
console.log(`Initial value of 'a.b.c.d':`);
|
|
56
|
+
expression.changed.subscribe((change) => {
|
|
57
|
+
printValue(change.value);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
console.log(
|
|
61
|
+
`Value of 'a.b.c.d' after changing 'a' to '{ b: Promise.resolve({ c: Promise.resolve({ d: 200 }) }) }':`,
|
|
62
|
+
);
|
|
63
|
+
await new WaitForEvent(expression, 'changed', {
|
|
64
|
+
ignoreInitialValue: true,
|
|
65
|
+
}).wait(() => {
|
|
66
|
+
expressionContext.a = {
|
|
67
|
+
b: Promise.resolve({ c: Promise.resolve({ d: 200 }) }),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
57
70
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
console.log(`Final value of 'a.b.c.d':`);
|
|
72
|
+
printValue(expression.value);
|
|
73
|
+
} finally {
|
|
74
|
+
// Always dispose of expressions after use.
|
|
75
|
+
expression.dispose();
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
```
|
|
66
79
|
|
|
67
80
|
- **Modular expressions** — expressions can reference other expressions:
|
|
68
81
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
```ts
|
|
83
|
+
const model = {
|
|
84
|
+
a: 10,
|
|
85
|
+
b: 20,
|
|
86
|
+
};
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
const expr1 = expressionFactory.create(model, '(a + 1)');
|
|
89
|
+
const expr2 = expressionFactory.create(model, '(b + 2)');
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
const modularModel = {
|
|
92
|
+
expr1,
|
|
93
|
+
expr2,
|
|
94
|
+
};
|
|
82
95
|
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
const expr3 = expressionFactory.create(modularModel, 'expr1 * expr2');
|
|
97
|
+
```
|
|
85
98
|
|
|
86
99
|
## Use cases
|
|
87
100
|
|
|
88
101
|
**Data binding for SPA frameworks and change detection** is the primary reason the expression parser was developed. However, it is a generic solution and can be used in any scenario where actions need to be triggered when data or an expression changes. Below are a few example use cases:
|
|
89
102
|
|
|
90
103
|
- **Logging and alert conditions**
|
|
91
|
-
Trigger alerts based on runtime conditions:
|
|
104
|
+
Trigger alerts based on runtime conditions:
|
|
92
105
|
- Monitoring systems
|
|
93
106
|
- Health checks
|
|
94
107
|
- Observability tools
|
|
95
|
-
|
|
96
108
|
- **UI logic outside data binding**
|
|
97
109
|
Declarative UI behavior without relying on a full framework.
|
|
98
110
|
|
|
99
|
-
- **Workflow and automation engines**
|
|
111
|
+
- **Workflow and automation engines**
|
|
100
112
|
- CI/CD pipelines
|
|
101
113
|
- Job schedulers
|
|
102
114
|
- Business process automation
|
|
103
|
-
|
|
104
|
-
- **Game logic and simulation**
|
|
115
|
+
- **Game logic and simulation**
|
|
105
116
|
- AI decision trees
|
|
106
117
|
- Ability unlock rules
|
|
107
118
|
- Physics toggles
|
|
108
|
-
|
|
109
|
-
- **Spreadsheet-like calculations**
|
|
119
|
+
- **Spreadsheet-like calculations**
|
|
110
120
|
- Financial dashboards
|
|
111
121
|
- Pricing calculators
|
|
112
122
|
- Quotation systems
|
|
113
|
-
-
|
|
123
|
+
-
|
|
114
124
|
- **Validation engines**
|
|
115
125
|
Field validation based on the values of other fields.
|
|
116
126
|
|
|
117
|
-
|
|
118
127
|
## Modular Expressions
|
|
119
128
|
|
|
120
129
|
RS-X supports **modular expressions**, allowing expressions to reference **other expressions** as first-class values.
|
|
121
130
|
|
|
122
131
|
This enables you to:
|
|
132
|
+
|
|
123
133
|
- Compose complex calculations from smaller, reusable parts
|
|
124
134
|
- Share intermediate results across multiple expressions
|
|
125
135
|
- Improve readability, maintainability, and testability
|
|
@@ -142,7 +152,7 @@ Each expression remains **observable**, and changes propagate efficiently throug
|
|
|
142
152
|
```ts
|
|
143
153
|
const model = {
|
|
144
154
|
a: 10,
|
|
145
|
-
b: 20
|
|
155
|
+
b: 20,
|
|
146
156
|
};
|
|
147
157
|
|
|
148
158
|
const expr1 = expressionFactory.create(model, '(a + 1)');
|
|
@@ -150,7 +160,7 @@ const expr2 = expressionFactory.create(model, '(b + 2)');
|
|
|
150
160
|
|
|
151
161
|
const modularModel = {
|
|
152
162
|
expr1,
|
|
153
|
-
expr2
|
|
163
|
+
expr2,
|
|
154
164
|
};
|
|
155
165
|
|
|
156
166
|
const expr3 = expressionFactory.create(modularModel, 'expr1 * expr2');
|
|
@@ -163,6 +173,7 @@ const expr3 = expressionFactory.create(modularModel, 'expr1 * expr2');
|
|
|
163
173
|
- `expr3` evaluates to `242`
|
|
164
174
|
|
|
165
175
|
When `a` or `b` changes:
|
|
176
|
+
|
|
166
177
|
- Only the affected expressions are recalculated
|
|
167
178
|
- Dependent expressions update automatically
|
|
168
179
|
|
|
@@ -177,6 +188,7 @@ expr3.changed.subscribe(() => {
|
|
|
177
188
|
```
|
|
178
189
|
|
|
179
190
|
Changes to:
|
|
191
|
+
|
|
180
192
|
- `a`
|
|
181
193
|
- `b`
|
|
182
194
|
- `expr1`
|
|
@@ -195,6 +207,7 @@ Modular expressions are not only about structure — they also **improve perform
|
|
|
195
207
|
- No duplicated computation for shared logic
|
|
196
208
|
|
|
197
209
|
This is especially important when:
|
|
210
|
+
|
|
198
211
|
- Expressions are computationally expensive
|
|
199
212
|
- Expressions depend on asynchronous or reactive data
|
|
200
213
|
- The same calculation is reused in multiple places (e.g. UI bindings)
|
|
@@ -205,7 +218,7 @@ Modular expression support is enabled by adding a **custom index accessor** and
|
|
|
205
218
|
|
|
206
219
|
This clearly illustrates the power of the expression parser: **new data types and reactive models can be seamlessly integrated** by extending the **State Manager** via plugins.
|
|
207
220
|
|
|
208
|
-
## Complex modular expression example
|
|
221
|
+
## Complex modular expression example
|
|
209
222
|
|
|
210
223
|
To get a sense of how powerful **modular expressions** are, we will look at a more realistic example.
|
|
211
224
|
We are going to create an expression that calculates **credit risk**.
|
|
@@ -215,50 +228,52 @@ First, we will show an implementation **without modular expressions**, followed
|
|
|
215
228
|
---
|
|
216
229
|
|
|
217
230
|
### Non-Modular example
|
|
231
|
+
|
|
218
232
|
```ts
|
|
219
233
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
220
234
|
import {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
235
|
+
IExpressionFactory,
|
|
236
|
+
RsXExpressionParserInjectionTokens,
|
|
237
|
+
RsXExpressionParserModule,
|
|
224
238
|
} from '@rs-x/expression-parser';
|
|
225
239
|
import { BehaviorSubject } from 'rxjs';
|
|
226
240
|
|
|
227
241
|
// Load the expression parser module into the injection container
|
|
228
242
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
229
|
-
const expressionFactory: IExpressionFactory =
|
|
230
|
-
|
|
243
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
244
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
245
|
+
);
|
|
231
246
|
|
|
232
247
|
export const run = (async () => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
248
|
+
interface IRisk {
|
|
249
|
+
volatilityIndex: number;
|
|
250
|
+
recessionProbability: number;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const riskModel = {
|
|
254
|
+
customer: {
|
|
255
|
+
age: 42,
|
|
256
|
+
income: 72000,
|
|
257
|
+
employmentYears: 6,
|
|
258
|
+
},
|
|
259
|
+
credit: {
|
|
260
|
+
score: 680,
|
|
261
|
+
outstandingDebt: 18000,
|
|
262
|
+
},
|
|
263
|
+
market: {
|
|
264
|
+
baseInterestRate: 0.035,
|
|
265
|
+
},
|
|
266
|
+
risk: new BehaviorSubject<IRisk>({
|
|
267
|
+
volatilityIndex: 0.28,
|
|
268
|
+
recessionProbability: 0.12,
|
|
269
|
+
}),
|
|
270
|
+
thresholds: {
|
|
271
|
+
highRisk: 0.75,
|
|
272
|
+
mediumRisk: 0.45,
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const expressionString = `(
|
|
262
277
|
(
|
|
263
278
|
// =========================
|
|
264
279
|
// Numeric risk score
|
|
@@ -324,39 +339,43 @@ export const run = (async () => {
|
|
|
324
339
|
)
|
|
325
340
|
)`;
|
|
326
341
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
console.log('Initial risk: ')
|
|
330
|
-
const changeSubscription = expression.changed.subscribe(() => {
|
|
331
|
-
console.log(expression.value);
|
|
332
|
-
});
|
|
342
|
+
const expression = expressionFactory.create(riskModel, expressionString);
|
|
333
343
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
console.log('Risk after changing risk parameters from { volatilityIndex: 0.28, recessionProbability: 0.12 } to { volatilityIndex: 0.41, recessionProbability: 0.35 } :')
|
|
339
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
340
|
-
riskModel.risk.next({
|
|
341
|
-
volatilityIndex: 0.45,
|
|
342
|
-
recessionProbability: 0.35
|
|
343
|
-
})
|
|
344
|
-
});
|
|
344
|
+
console.log('Initial risk: ');
|
|
345
|
+
const changeSubscription = expression.changed.subscribe(() => {
|
|
346
|
+
console.log(expression.value);
|
|
347
|
+
});
|
|
345
348
|
|
|
346
|
-
|
|
349
|
+
try {
|
|
350
|
+
// Wait until the expression has been resolved (has a value)
|
|
351
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
347
352
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
})
|
|
353
|
+
console.log(
|
|
354
|
+
'Risk after changing risk parameters from { volatilityIndex: 0.28, recessionProbability: 0.12 } to { volatilityIndex: 0.41, recessionProbability: 0.35 } :',
|
|
355
|
+
);
|
|
356
|
+
await new WaitForEvent(expression, 'changed', {
|
|
357
|
+
ignoreInitialValue: true,
|
|
358
|
+
}).wait(() => {
|
|
359
|
+
riskModel.risk.next({
|
|
360
|
+
volatilityIndex: 0.45,
|
|
361
|
+
recessionProbability: 0.35,
|
|
362
|
+
});
|
|
363
|
+
});
|
|
358
364
|
|
|
365
|
+
console.log('Risk after change age = 63 and employmentYears = 1 ');
|
|
359
366
|
|
|
367
|
+
await new WaitForEvent(expression, 'changed', {
|
|
368
|
+
ignoreInitialValue: true,
|
|
369
|
+
}).wait(() => {
|
|
370
|
+
riskModel.customer.age = 63;
|
|
371
|
+
riskModel.customer.employmentYears = 1;
|
|
372
|
+
});
|
|
373
|
+
} finally {
|
|
374
|
+
changeSubscription.unsubscribe();
|
|
375
|
+
// Always dispose of expressions after use.
|
|
376
|
+
expression.dispose();
|
|
377
|
+
}
|
|
378
|
+
})();
|
|
360
379
|
```
|
|
361
380
|
|
|
362
381
|
### Modular example
|
|
@@ -364,131 +383,151 @@ export const run = (async () => {
|
|
|
364
383
|
```ts
|
|
365
384
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
366
385
|
import {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
386
|
+
IExpressionFactory,
|
|
387
|
+
RsXExpressionParserInjectionTokens,
|
|
388
|
+
RsXExpressionParserModule,
|
|
370
389
|
} from '@rs-x/expression-parser';
|
|
371
390
|
import { BehaviorSubject } from 'rxjs';
|
|
372
391
|
|
|
373
392
|
// Load the expression parser module into the injection container
|
|
374
393
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
375
|
-
const expressionFactory: IExpressionFactory =
|
|
376
|
-
|
|
377
|
-
|
|
394
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
395
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
396
|
+
);
|
|
378
397
|
|
|
379
398
|
export const run = (async () => {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
399
|
+
interface IRisk {
|
|
400
|
+
volatilityIndex: number;
|
|
401
|
+
recessionProbability: number;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const riskModel = {
|
|
405
|
+
customer: {
|
|
406
|
+
age: 42,
|
|
407
|
+
income: 72000,
|
|
408
|
+
employmentYears: 6,
|
|
409
|
+
},
|
|
410
|
+
credit: {
|
|
411
|
+
score: 680,
|
|
412
|
+
outstandingDebt: 18000,
|
|
413
|
+
},
|
|
414
|
+
market: {
|
|
415
|
+
baseInterestRate: 0.035,
|
|
416
|
+
},
|
|
417
|
+
risk: new BehaviorSubject<IRisk>({
|
|
418
|
+
volatilityIndex: 0.28,
|
|
419
|
+
recessionProbability: 0.12,
|
|
420
|
+
}),
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const basePersonalRisk = expressionFactory.create(
|
|
424
|
+
riskModel,
|
|
425
|
+
`
|
|
405
426
|
(credit.score < 600 ? 0.4 : 0.1) +
|
|
406
427
|
(credit.outstandingDebt / customer.income) * 0.6 -
|
|
407
428
|
(customer.employmentYears * 0.03)
|
|
408
|
-
|
|
429
|
+
`,
|
|
430
|
+
);
|
|
409
431
|
|
|
410
|
-
|
|
432
|
+
const ageBasedRiskAdjustment = expressionFactory.create(
|
|
433
|
+
riskModel,
|
|
434
|
+
`
|
|
411
435
|
customer.age < 25 ? 0.15 :
|
|
412
436
|
customer.age < 35 ? 0.05 :
|
|
413
437
|
customer.age < 55 ? 0.00 :
|
|
414
438
|
0.08
|
|
415
|
-
|
|
439
|
+
`,
|
|
440
|
+
);
|
|
416
441
|
|
|
417
|
-
|
|
442
|
+
const marketRisk = expressionFactory.create(
|
|
443
|
+
riskModel,
|
|
444
|
+
`
|
|
418
445
|
(risk.volatilityIndex * 0.5) +
|
|
419
446
|
(risk.recessionProbability * 0.5)
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
447
|
+
`,
|
|
448
|
+
);
|
|
449
|
+
|
|
450
|
+
const interestRateImpact = expressionFactory.create(
|
|
451
|
+
riskModel,
|
|
452
|
+
'market.baseInterestRate * 2',
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const riskScoreModel = {
|
|
456
|
+
basePersonalRisk,
|
|
457
|
+
ageBasedRiskAdjustment,
|
|
458
|
+
marketRisk,
|
|
459
|
+
interestRateImpact,
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
const riskScore = expressionFactory.create(
|
|
463
|
+
riskScoreModel,
|
|
464
|
+
`
|
|
432
465
|
basePersonalRisk +
|
|
433
466
|
ageBasedRiskAdjustment +
|
|
434
467
|
marketRisk +
|
|
435
468
|
interestRateImpact
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
|
|
469
|
+
`,
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
const riskClassificationModel = {
|
|
473
|
+
riskScore,
|
|
474
|
+
thresholds: {
|
|
475
|
+
highRisk: 0.75,
|
|
476
|
+
mediumRisk: 0.45,
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
const riskClassification = expressionFactory.create(
|
|
481
|
+
riskClassificationModel,
|
|
482
|
+
`
|
|
447
483
|
riskScore >= thresholds.highRisk
|
|
448
484
|
? 'HIGH'
|
|
449
485
|
: riskScore >= thresholds.mediumRisk
|
|
450
486
|
? 'MEDIUM'
|
|
451
487
|
: 'LOW'
|
|
452
|
-
|
|
488
|
+
`,
|
|
489
|
+
);
|
|
453
490
|
|
|
491
|
+
console.log('Initial risk: ');
|
|
492
|
+
const changeSubscription = riskClassification.changed.subscribe(() => {
|
|
493
|
+
console.log(riskClassification.value);
|
|
494
|
+
});
|
|
454
495
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
try {
|
|
461
|
-
// Wait until the expression has been resolved (has a value)
|
|
462
|
-
await new WaitForEvent(riskClassification, 'changed').wait(emptyFunction);
|
|
463
|
-
|
|
464
|
-
console.log('Risk after changing risk parameters from { volatilityIndex: 0.28, recessionProbability: 0.12 } to { volatilityIndex: 0.41, recessionProbability: 0.35 } :')
|
|
465
|
-
await new WaitForEvent(riskClassification, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
466
|
-
riskModel.risk.next({
|
|
467
|
-
volatilityIndex: 0.45,
|
|
468
|
-
recessionProbability: 0.35
|
|
469
|
-
})
|
|
470
|
-
});
|
|
496
|
+
try {
|
|
497
|
+
// Wait until the expression has been resolved (has a value)
|
|
498
|
+
await new WaitForEvent(riskClassification, 'changed').wait(emptyFunction);
|
|
471
499
|
|
|
472
|
-
|
|
500
|
+
console.log(
|
|
501
|
+
'Risk after changing risk parameters from { volatilityIndex: 0.28, recessionProbability: 0.12 } to { volatilityIndex: 0.41, recessionProbability: 0.35 } :',
|
|
502
|
+
);
|
|
503
|
+
await new WaitForEvent(riskClassification, 'changed', {
|
|
504
|
+
ignoreInitialValue: true,
|
|
505
|
+
}).wait(() => {
|
|
506
|
+
riskModel.risk.next({
|
|
507
|
+
volatilityIndex: 0.45,
|
|
508
|
+
recessionProbability: 0.35,
|
|
509
|
+
});
|
|
510
|
+
});
|
|
473
511
|
|
|
474
|
-
|
|
475
|
-
riskModel.customer.age = 63;
|
|
476
|
-
riskModel.customer.employmentYears = 1;
|
|
477
|
-
});
|
|
512
|
+
console.log('Risk after change age = 63 and employmentYears = 1 ');
|
|
478
513
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
514
|
+
await new WaitForEvent(riskClassification, 'changed', {
|
|
515
|
+
ignoreInitialValue: true,
|
|
516
|
+
}).wait(() => {
|
|
517
|
+
riskModel.customer.age = 63;
|
|
518
|
+
riskModel.customer.employmentYears = 1;
|
|
519
|
+
});
|
|
520
|
+
} finally {
|
|
521
|
+
changeSubscription.unsubscribe();
|
|
522
|
+
// Always dispose of expressions after use.
|
|
523
|
+
riskClassification.dispose();
|
|
524
|
+
riskScore.dispose();
|
|
525
|
+
interestRateImpact.dispose();
|
|
526
|
+
marketRisk.dispose();
|
|
527
|
+
ageBasedRiskAdjustment.dispose();
|
|
528
|
+
basePersonalRisk.dispose();
|
|
529
|
+
}
|
|
489
530
|
})();
|
|
490
|
-
|
|
491
|
-
|
|
492
531
|
```
|
|
493
532
|
|
|
494
533
|
### Limitations of the Non-Modular Implementation
|
|
@@ -528,8 +567,8 @@ to use it.
|
|
|
528
567
|
```ts
|
|
529
568
|
import { InjectionContainer } from '@rs-x/core';
|
|
530
569
|
import {
|
|
531
|
-
|
|
532
|
-
|
|
570
|
+
RsXExpressionParserInjectionTokens,
|
|
571
|
+
RsXExpressionParserModule,
|
|
533
572
|
} from '@rs-x/expression-parser';
|
|
534
573
|
|
|
535
574
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
@@ -539,45 +578,45 @@ There are two ways to get an instance:
|
|
|
539
578
|
|
|
540
579
|
1. Using the injection container
|
|
541
580
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
581
|
+
```ts
|
|
582
|
+
import { InjectionContainer } from '@rs-x/core';
|
|
583
|
+
import {
|
|
584
|
+
IExpressionFactory,
|
|
585
|
+
RsXExpressionParserInjectionTokens,
|
|
586
|
+
RsXExpressionParserModule,
|
|
587
|
+
} from '@rs-x/expression-parser';
|
|
549
588
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
589
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
590
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
591
|
+
);
|
|
592
|
+
```
|
|
554
593
|
|
|
555
594
|
2. Using the `@Inject` decorator
|
|
556
595
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
```
|
|
596
|
+
```ts
|
|
597
|
+
import { Inject } from '@rs-x/core';
|
|
598
|
+
import {
|
|
599
|
+
RsXExpressionParserInjectionTokens,
|
|
600
|
+
RsXExpressionParserModule,
|
|
601
|
+
} from '@rs-x/expression-parser';
|
|
602
|
+
|
|
603
|
+
export class MyClass {
|
|
604
|
+
constructor(
|
|
605
|
+
@Inject(RsXExpressionParserInjectionTokens.IExpressionFactory)
|
|
606
|
+
private readonly _expressionFactory: IExpressionFactory,
|
|
607
|
+
) {}
|
|
608
|
+
}
|
|
609
|
+
```
|
|
572
610
|
|
|
573
611
|
## Resolving Identifier Owner
|
|
574
612
|
|
|
575
613
|
Expressions resolve to data values for there leaves. These values may be constants (such as numbers or strings), but more commonly they are stored as **indexes** within a given **context**. For example, when the context is an object instance, indexes refer to properties or fields; when the context is a `Map`, indexes refer to map keys.
|
|
576
614
|
|
|
577
615
|
The interface responsible for resolving the owner of an identifier is defined as follows:
|
|
616
|
+
|
|
578
617
|
```ts
|
|
579
618
|
export interface IIdentifierOwnerResolver {
|
|
580
|
-
|
|
619
|
+
resolve(index: unknown, context: unknown): object | null;
|
|
581
620
|
}
|
|
582
621
|
```
|
|
583
622
|
|
|
@@ -587,13 +626,22 @@ In `rs-x-expression-parser.module.ts`, the default resolver list is configured a
|
|
|
587
626
|
|
|
588
627
|
```ts
|
|
589
628
|
registerMultiInjectServices(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
629
|
+
options,
|
|
630
|
+
RsXExpressionParserInjectionTokens.IIdentifierOwnerResolverList,
|
|
631
|
+
[
|
|
632
|
+
{
|
|
633
|
+
target: PropertyOwnerResolver,
|
|
634
|
+
token: RsXExpressionParserInjectionTokens.PropertyOwnerResolver,
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
target: ArrayIndexOwnerResolver,
|
|
638
|
+
token: RsXExpressionParserInjectionTokens.ArrayIndexOwnerResolver,
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
target: MapKeyOwnerResolver,
|
|
642
|
+
token: RsXExpressionParserInjectionTokens.MapKeyOwnerResolver,
|
|
643
|
+
},
|
|
644
|
+
],
|
|
597
645
|
);
|
|
598
646
|
```
|
|
599
647
|
|
|
@@ -609,18 +657,19 @@ The default configuration includes the following resolvers:
|
|
|
609
657
|
Resolves the identifier if the context is a `Map` and the specified index exists as a key in that map. Returns the context if resolved; otherwise, returns `null`.
|
|
610
658
|
|
|
611
659
|
The default resolver list may be overridden by registering a custom list in a consuming module:
|
|
660
|
+
|
|
612
661
|
```ts
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
662
|
+
overrideMultiInjectServices(
|
|
663
|
+
options,
|
|
664
|
+
RsXExpressionParserInjectionTokens.IIdentifierOwnerResolverList,
|
|
665
|
+
CUSTOM_LIST,
|
|
666
|
+
);
|
|
618
667
|
```
|
|
668
|
+
|
|
619
669
|
A common use case for a custom resolver occurs during data binding. In such scenarios, the initial context is the HTML element on which the data-binding expression is declared, while the identifier may be defined on an ancestor element (for example, a custom element). In this case, the resolver must traverse the parent chain until an element defining the identifier is found. The resolved context is then that element.
|
|
620
670
|
|
|
621
671
|
This behavior can be implemented by providing a custom `IIdentifierOwnerResolver` that encapsulates the required traversal logic.
|
|
622
672
|
|
|
623
|
-
|
|
624
673
|
## Supported Expresssion types
|
|
625
674
|
|
|
626
675
|
All non-assignment JavaScript expressions are supported. These expressions can be combined to form more complex expressions. The following expressions are the basic supported expressions:
|
|
@@ -630,95 +679,129 @@ All non-assignment JavaScript expressions are supported. These expressions can b
|
|
|
630
679
|
```ts
|
|
631
680
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
632
681
|
import {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
682
|
+
IExpressionFactory,
|
|
683
|
+
RsXExpressionParserInjectionTokens,
|
|
684
|
+
RsXExpressionParserModule,
|
|
636
685
|
} from '@rs-x/expression-parser';
|
|
637
686
|
|
|
638
687
|
// Load the expression parser module into the injection container
|
|
639
688
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
640
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
689
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
690
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
691
|
+
);
|
|
641
692
|
|
|
642
693
|
export const run = (async () => {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
694
|
+
const expressionContext = {
|
|
695
|
+
a: 1,
|
|
696
|
+
b: 3,
|
|
697
|
+
};
|
|
647
698
|
|
|
648
|
-
|
|
699
|
+
const expression = expressionFactory.create(expressionContext, 'a + b');
|
|
649
700
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
701
|
+
try {
|
|
702
|
+
// Wait until the expression has been resolved (has a value)
|
|
703
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
653
704
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
705
|
+
console.log(`Initial value of 'a + b':`);
|
|
706
|
+
expression.changed.subscribe((change) => {
|
|
707
|
+
console.log(change.value);
|
|
708
|
+
});
|
|
658
709
|
|
|
659
|
-
|
|
660
|
-
|
|
710
|
+
console.log(`Value of 'a + b' after changing 'a' to '6':`);
|
|
711
|
+
await new WaitForEvent(expression, 'changed', {
|
|
712
|
+
ignoreInitialValue: true,
|
|
713
|
+
}).wait(() => {
|
|
714
|
+
expressionContext.a = 6;
|
|
715
|
+
});
|
|
661
716
|
|
|
662
|
-
|
|
663
|
-
|
|
717
|
+
console.log(`Value of 'a + b' after changing 'b' to '4':`);
|
|
718
|
+
await new WaitForEvent(expression, 'changed', {
|
|
719
|
+
ignoreInitialValue: true,
|
|
720
|
+
}).wait(() => {
|
|
721
|
+
expressionContext.b = 4;
|
|
722
|
+
});
|
|
664
723
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
724
|
+
console.log(`Final value of 'a + b':`);
|
|
725
|
+
console.log(expression.value);
|
|
726
|
+
} finally {
|
|
727
|
+
// Always dispose of expressions after use.
|
|
728
|
+
expression.dispose();
|
|
729
|
+
}
|
|
671
730
|
})();
|
|
672
|
-
|
|
673
|
-
|
|
674
731
|
```
|
|
675
732
|
|
|
676
733
|
### Array expression
|
|
677
734
|
|
|
678
735
|
```ts
|
|
679
|
-
import { emptyFunction, InjectionContainer, printValue, WaitForEvent } from '@rs-x/core';
|
|
680
736
|
import {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
737
|
+
emptyFunction,
|
|
738
|
+
InjectionContainer,
|
|
739
|
+
printValue,
|
|
740
|
+
WaitForEvent,
|
|
741
|
+
} from '@rs-x/core';
|
|
742
|
+
import {
|
|
743
|
+
IExpressionFactory,
|
|
744
|
+
RsXExpressionParserInjectionTokens,
|
|
745
|
+
RsXExpressionParserModule,
|
|
684
746
|
} from '@rs-x/expression-parser';
|
|
685
747
|
|
|
686
748
|
// Load the expression parser module into the injection container
|
|
687
749
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
688
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
750
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
751
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
752
|
+
);
|
|
689
753
|
|
|
690
754
|
export const run = (async () => {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
755
|
+
const expressionContext = {
|
|
756
|
+
a: 3,
|
|
757
|
+
array: [1, 2],
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
const expression = expressionFactory.create(
|
|
761
|
+
expressionContext,
|
|
762
|
+
'[a, ...array, 100]',
|
|
763
|
+
);
|
|
764
|
+
|
|
765
|
+
try {
|
|
766
|
+
// Wait until the expression has been resolved (has a value)
|
|
767
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
768
|
+
|
|
769
|
+
console.log(`Initial value of '[a, ...array, 100]':`);
|
|
770
|
+
expression.changed.subscribe((change) => {
|
|
771
|
+
printValue(change.value);
|
|
772
|
+
});
|
|
706
773
|
|
|
707
|
-
|
|
708
|
-
|
|
774
|
+
console.log(`Value of [a, ...array, 100]' after changing 'a' to '6':`);
|
|
775
|
+
await new WaitForEvent(expression, 'changed', {
|
|
776
|
+
ignoreInitialValue: true,
|
|
777
|
+
}).wait(() => {
|
|
778
|
+
expressionContext.a = 6;
|
|
779
|
+
});
|
|
709
780
|
|
|
710
|
-
|
|
711
|
-
|
|
781
|
+
console.log(
|
|
782
|
+
`Value of '[a, ...array, 100]' after changing 'array' to '[1, 2, 3]':`,
|
|
783
|
+
);
|
|
784
|
+
await new WaitForEvent(expression, 'changed', {
|
|
785
|
+
ignoreInitialValue: true,
|
|
786
|
+
}).wait(() => {
|
|
787
|
+
expressionContext.array.push(3);
|
|
788
|
+
});
|
|
712
789
|
|
|
713
|
-
|
|
714
|
-
|
|
790
|
+
console.log(
|
|
791
|
+
`Value of '[a, ...array, 100]' after setting 'array' to '[100, 200]':`,
|
|
792
|
+
);
|
|
793
|
+
await new WaitForEvent(expression, 'changed', {
|
|
794
|
+
ignoreInitialValue: true,
|
|
795
|
+
}).wait(() => {
|
|
796
|
+
expressionContext.array = [100, 200];
|
|
797
|
+
});
|
|
715
798
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
799
|
+
console.log(`Final value of '[a, ...array, 100]':`);
|
|
800
|
+
printValue(expression.value);
|
|
801
|
+
} finally {
|
|
802
|
+
// Always dispose of expressions after use.
|
|
803
|
+
expression.dispose();
|
|
804
|
+
}
|
|
722
805
|
})();
|
|
723
806
|
```
|
|
724
807
|
|
|
@@ -727,46 +810,55 @@ export const run = (async () => {
|
|
|
727
810
|
```ts
|
|
728
811
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
729
812
|
import {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
813
|
+
IExpressionFactory,
|
|
814
|
+
RsXExpressionParserInjectionTokens,
|
|
815
|
+
RsXExpressionParserModule,
|
|
733
816
|
} from '@rs-x/expression-parser';
|
|
734
817
|
|
|
735
818
|
// Load the expression parser module into the injection container
|
|
736
819
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
737
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
820
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
821
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
822
|
+
);
|
|
738
823
|
|
|
739
824
|
export const run = (async () => {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
825
|
+
const expressionContext = {
|
|
826
|
+
a: 5,
|
|
827
|
+
b: 3,
|
|
828
|
+
};
|
|
744
829
|
|
|
745
|
-
|
|
830
|
+
const expression = expressionFactory.create(expressionContext, 'a & b');
|
|
746
831
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
832
|
+
try {
|
|
833
|
+
// Wait until the expression has been resolved (has a value)
|
|
834
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
750
835
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
836
|
+
console.log(`Initial value of 'a & b':`);
|
|
837
|
+
expression.changed.subscribe((change) => {
|
|
838
|
+
console.log(change.value);
|
|
839
|
+
});
|
|
755
840
|
|
|
756
|
-
|
|
757
|
-
|
|
841
|
+
console.log(`Value of 'a & b' after changing 'a' to '2':`);
|
|
842
|
+
await new WaitForEvent(expression, 'changed', {
|
|
843
|
+
ignoreInitialValue: true,
|
|
844
|
+
}).wait(() => {
|
|
845
|
+
expressionContext.a = 2;
|
|
846
|
+
});
|
|
758
847
|
|
|
759
|
-
|
|
760
|
-
|
|
848
|
+
console.log(`Value of 'a & b' after changing 'b' to '8':`);
|
|
849
|
+
await new WaitForEvent(expression, 'changed', {
|
|
850
|
+
ignoreInitialValue: true,
|
|
851
|
+
}).wait(() => {
|
|
852
|
+
expressionContext.b = 8;
|
|
853
|
+
});
|
|
761
854
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
855
|
+
console.log(`Final value of 'a & b':`);
|
|
856
|
+
console.log(expression.value);
|
|
857
|
+
} finally {
|
|
858
|
+
// Always dispose of expressions after use.
|
|
859
|
+
expression.dispose();
|
|
860
|
+
}
|
|
768
861
|
})();
|
|
769
|
-
|
|
770
862
|
```
|
|
771
863
|
|
|
772
864
|
### Bitwise left shift expression
|
|
@@ -774,48 +866,55 @@ export const run = (async () => {
|
|
|
774
866
|
```ts
|
|
775
867
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
776
868
|
import {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
869
|
+
IExpressionFactory,
|
|
870
|
+
RsXExpressionParserInjectionTokens,
|
|
871
|
+
RsXExpressionParserModule,
|
|
780
872
|
} from '@rs-x/expression-parser';
|
|
781
873
|
|
|
782
874
|
// Load the expression parser module into the injection container
|
|
783
875
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
784
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
876
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
877
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
878
|
+
);
|
|
785
879
|
|
|
786
880
|
export const run = (async () => {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
881
|
+
const expressionContext = {
|
|
882
|
+
a: 5,
|
|
883
|
+
b: 2,
|
|
884
|
+
};
|
|
791
885
|
|
|
792
|
-
|
|
886
|
+
const expression = expressionFactory.create(expressionContext, 'a << b');
|
|
793
887
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
888
|
+
try {
|
|
889
|
+
// Wait until the expression has been resolved (has a value)
|
|
890
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
797
891
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
892
|
+
console.log(`Initial value of 'a << b':`);
|
|
893
|
+
expression.changed.subscribe((change) => {
|
|
894
|
+
console.log(change.value);
|
|
895
|
+
});
|
|
802
896
|
|
|
803
|
-
|
|
804
|
-
|
|
897
|
+
console.log(`Value of 'a << b' after changing 'a' to '4':`);
|
|
898
|
+
await new WaitForEvent(expression, 'changed', {
|
|
899
|
+
ignoreInitialValue: true,
|
|
900
|
+
}).wait(() => {
|
|
901
|
+
expressionContext.a = 4;
|
|
902
|
+
});
|
|
805
903
|
|
|
806
|
-
|
|
807
|
-
|
|
904
|
+
console.log(`Value of 'a << b' after changing 'b' to '3':`);
|
|
905
|
+
await new WaitForEvent(expression, 'changed', {
|
|
906
|
+
ignoreInitialValue: true,
|
|
907
|
+
}).wait(() => {
|
|
908
|
+
expressionContext.b = 3;
|
|
909
|
+
});
|
|
808
910
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
911
|
+
console.log(`Final value of 'a << b':`);
|
|
912
|
+
console.log(expression.value);
|
|
913
|
+
} finally {
|
|
914
|
+
// Always dispose of expressions after use.
|
|
915
|
+
expression.dispose();
|
|
916
|
+
}
|
|
815
917
|
})();
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
918
|
```
|
|
820
919
|
|
|
821
920
|
### Bitwise not expression
|
|
@@ -823,43 +922,47 @@ export const run = (async () => {
|
|
|
823
922
|
```ts
|
|
824
923
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
825
924
|
import {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
925
|
+
IExpressionFactory,
|
|
926
|
+
RsXExpressionParserInjectionTokens,
|
|
927
|
+
RsXExpressionParserModule,
|
|
829
928
|
} from '@rs-x/expression-parser';
|
|
830
929
|
|
|
831
930
|
// Load the expression parser module into the injection container
|
|
832
931
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
833
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
834
|
-
|
|
932
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
933
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
934
|
+
);
|
|
835
935
|
|
|
836
936
|
export const run = (async () => {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
937
|
+
const expressionContext = {
|
|
938
|
+
a: 5,
|
|
939
|
+
};
|
|
840
940
|
|
|
841
|
-
|
|
941
|
+
const expression = expressionFactory.create(expressionContext, '~a');
|
|
842
942
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
943
|
+
try {
|
|
944
|
+
// Wait until the expression has been resolved (has a value)
|
|
945
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
846
946
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
947
|
+
console.log(`Initial value of '~a':`);
|
|
948
|
+
expression.changed.subscribe((change) => {
|
|
949
|
+
console.log(change.value);
|
|
950
|
+
});
|
|
851
951
|
|
|
852
|
-
|
|
853
|
-
|
|
952
|
+
console.log(`Value of ~a' after changing 'a' to '3':`);
|
|
953
|
+
await new WaitForEvent(expression, 'changed', {
|
|
954
|
+
ignoreInitialValue: true,
|
|
955
|
+
}).wait(() => {
|
|
956
|
+
expressionContext.a = 3;
|
|
957
|
+
});
|
|
854
958
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
959
|
+
console.log(`Final value of '~a':`);
|
|
960
|
+
console.log(expression.value);
|
|
961
|
+
} finally {
|
|
962
|
+
// Always dispose of expressions after use.
|
|
963
|
+
expression.dispose();
|
|
964
|
+
}
|
|
861
965
|
})();
|
|
862
|
-
|
|
863
966
|
```
|
|
864
967
|
|
|
865
968
|
### Bitwise or expression
|
|
@@ -867,47 +970,55 @@ export const run = (async () => {
|
|
|
867
970
|
```ts
|
|
868
971
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
869
972
|
import {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
973
|
+
IExpressionFactory,
|
|
974
|
+
RsXExpressionParserInjectionTokens,
|
|
975
|
+
RsXExpressionParserModule,
|
|
873
976
|
} from '@rs-x/expression-parser';
|
|
874
977
|
|
|
875
978
|
// Load the expression parser module into the injection container
|
|
876
979
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
877
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
980
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
981
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
982
|
+
);
|
|
878
983
|
|
|
879
984
|
export const run = (async () => {
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
985
|
+
const expressionContext = {
|
|
986
|
+
a: 5,
|
|
987
|
+
b: 2,
|
|
988
|
+
};
|
|
884
989
|
|
|
885
|
-
|
|
990
|
+
const expression = expressionFactory.create(expressionContext, 'a | b');
|
|
886
991
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
992
|
+
try {
|
|
993
|
+
// Wait until the expression has been resolved (has a value)
|
|
994
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
890
995
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
996
|
+
console.log(`Initial value of 'a | b':`);
|
|
997
|
+
expression.changed.subscribe((change) => {
|
|
998
|
+
console.log(change.value);
|
|
999
|
+
});
|
|
895
1000
|
|
|
896
|
-
|
|
897
|
-
|
|
1001
|
+
console.log(`Value of 'a | b' after changing 'a' to '10':`);
|
|
1002
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1003
|
+
ignoreInitialValue: true,
|
|
1004
|
+
}).wait(() => {
|
|
1005
|
+
expressionContext.a = 10;
|
|
1006
|
+
});
|
|
898
1007
|
|
|
899
|
-
|
|
900
|
-
|
|
1008
|
+
console.log(`Value of 'a | b' after changing 'b' to '3':`);
|
|
1009
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1010
|
+
ignoreInitialValue: true,
|
|
1011
|
+
}).wait(() => {
|
|
1012
|
+
expressionContext.b = 3;
|
|
1013
|
+
});
|
|
901
1014
|
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1015
|
+
console.log(`Final value of 'a | b':`);
|
|
1016
|
+
console.log(expression.value);
|
|
1017
|
+
} finally {
|
|
1018
|
+
// Always dispose of expressions after use.
|
|
1019
|
+
expression.dispose();
|
|
1020
|
+
}
|
|
908
1021
|
})();
|
|
909
|
-
|
|
910
|
-
|
|
911
1022
|
```
|
|
912
1023
|
|
|
913
1024
|
### Bitwise right shift expression
|
|
@@ -915,48 +1026,55 @@ export const run = (async () => {
|
|
|
915
1026
|
```ts
|
|
916
1027
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
917
1028
|
import {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1029
|
+
IExpressionFactory,
|
|
1030
|
+
RsXExpressionParserInjectionTokens,
|
|
1031
|
+
RsXExpressionParserModule,
|
|
921
1032
|
} from '@rs-x/expression-parser';
|
|
922
1033
|
|
|
923
|
-
|
|
924
1034
|
// Load the expression parser module into the injection container
|
|
925
1035
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
926
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1036
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1037
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1038
|
+
);
|
|
927
1039
|
|
|
928
1040
|
export const run = (async () => {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1041
|
+
const expressionContext = {
|
|
1042
|
+
a: 5,
|
|
1043
|
+
b: 2,
|
|
1044
|
+
};
|
|
933
1045
|
|
|
934
|
-
|
|
1046
|
+
const expression = expressionFactory.create(expressionContext, 'a >> b');
|
|
935
1047
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
1048
|
+
try {
|
|
1049
|
+
// Wait until the expression has been resolved (has a value)
|
|
1050
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
939
1051
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1052
|
+
console.log(`Initial value of 'a >> b':`);
|
|
1053
|
+
expression.changed.subscribe((change) => {
|
|
1054
|
+
console.log(change.value);
|
|
1055
|
+
});
|
|
944
1056
|
|
|
945
|
-
|
|
946
|
-
|
|
1057
|
+
console.log(`Value of 'a >> b' after changing 'a' to '10':`);
|
|
1058
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1059
|
+
ignoreInitialValue: true,
|
|
1060
|
+
}).wait(() => {
|
|
1061
|
+
expressionContext.a = 10;
|
|
1062
|
+
});
|
|
947
1063
|
|
|
948
|
-
|
|
949
|
-
|
|
1064
|
+
console.log(`Value of 'a >> b' after changing 'b' to '3':`);
|
|
1065
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1066
|
+
ignoreInitialValue: true,
|
|
1067
|
+
}).wait(() => {
|
|
1068
|
+
expressionContext.b = 3;
|
|
1069
|
+
});
|
|
950
1070
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1071
|
+
console.log(`Final value of 'a >> b':`);
|
|
1072
|
+
console.log(expression.value);
|
|
1073
|
+
} finally {
|
|
1074
|
+
// Always dispose of expressions after use.
|
|
1075
|
+
expression.dispose();
|
|
1076
|
+
}
|
|
957
1077
|
})();
|
|
958
|
-
|
|
959
|
-
|
|
960
1078
|
```
|
|
961
1079
|
|
|
962
1080
|
### Bitwise unsigned right shift expression
|
|
@@ -964,47 +1082,55 @@ export const run = (async () => {
|
|
|
964
1082
|
```ts
|
|
965
1083
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
966
1084
|
import {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1085
|
+
IExpressionFactory,
|
|
1086
|
+
RsXExpressionParserInjectionTokens,
|
|
1087
|
+
RsXExpressionParserModule,
|
|
970
1088
|
} from '@rs-x/expression-parser';
|
|
971
1089
|
|
|
972
1090
|
// Load the expression parser module into the injection container
|
|
973
1091
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
974
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1092
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1093
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1094
|
+
);
|
|
975
1095
|
|
|
976
1096
|
export const run = (async () => {
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1097
|
+
const expressionContext = {
|
|
1098
|
+
a: 5,
|
|
1099
|
+
b: 2,
|
|
1100
|
+
};
|
|
981
1101
|
|
|
982
|
-
|
|
1102
|
+
const expression = expressionFactory.create(expressionContext, 'a >>> b');
|
|
983
1103
|
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1104
|
+
try {
|
|
1105
|
+
// Wait until the expression has been resolved (has a value)
|
|
1106
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
987
1107
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1108
|
+
console.log(`Initial value of 'a >>> b':`);
|
|
1109
|
+
expression.changed.subscribe((change) => {
|
|
1110
|
+
console.log(change.value);
|
|
1111
|
+
});
|
|
992
1112
|
|
|
993
|
-
|
|
994
|
-
|
|
1113
|
+
console.log(`Value of 'a >>> b' after changing 'a' to '-5':`);
|
|
1114
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1115
|
+
ignoreInitialValue: true,
|
|
1116
|
+
}).wait(() => {
|
|
1117
|
+
expressionContext.a = -5;
|
|
1118
|
+
});
|
|
995
1119
|
|
|
996
|
-
|
|
997
|
-
|
|
1120
|
+
console.log(`Value of 'a >>> b' after changing 'b' to '3':`);
|
|
1121
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1122
|
+
ignoreInitialValue: true,
|
|
1123
|
+
}).wait(() => {
|
|
1124
|
+
expressionContext.b = 3;
|
|
1125
|
+
});
|
|
998
1126
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1127
|
+
console.log(`Final value of 'a >>> b':`);
|
|
1128
|
+
console.log(expression.value);
|
|
1129
|
+
} finally {
|
|
1130
|
+
// Always dispose of expressions after use.
|
|
1131
|
+
expression.dispose();
|
|
1132
|
+
}
|
|
1005
1133
|
})();
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
1134
|
```
|
|
1009
1135
|
|
|
1010
1136
|
### Bitwise xor expression
|
|
@@ -1012,46 +1138,55 @@ export const run = (async () => {
|
|
|
1012
1138
|
```ts
|
|
1013
1139
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1014
1140
|
import {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1141
|
+
IExpressionFactory,
|
|
1142
|
+
RsXExpressionParserInjectionTokens,
|
|
1143
|
+
RsXExpressionParserModule,
|
|
1018
1144
|
} from '@rs-x/expression-parser';
|
|
1019
1145
|
|
|
1020
1146
|
// Load the expression parser module into the injection container
|
|
1021
1147
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1022
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1148
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1149
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1150
|
+
);
|
|
1023
1151
|
|
|
1024
1152
|
export const run = (async () => {
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1153
|
+
const expressionContext = {
|
|
1154
|
+
a: 5,
|
|
1155
|
+
b: 3,
|
|
1156
|
+
};
|
|
1029
1157
|
|
|
1030
|
-
|
|
1158
|
+
const expression = expressionFactory.create(expressionContext, 'a ^ b');
|
|
1031
1159
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1160
|
+
try {
|
|
1161
|
+
// Wait until the expression has been resolved (has a value)
|
|
1162
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1035
1163
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1164
|
+
console.log(`Initial value of 'a ^ b':`);
|
|
1165
|
+
expression.changed.subscribe((change) => {
|
|
1166
|
+
console.log(change.value);
|
|
1167
|
+
});
|
|
1040
1168
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1169
|
+
console.log(`Value of 'a ^ b' after changing 'a' to '10':`);
|
|
1170
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1171
|
+
ignoreInitialValue: true,
|
|
1172
|
+
}).wait(() => {
|
|
1173
|
+
expressionContext.a = 10;
|
|
1174
|
+
});
|
|
1043
1175
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1176
|
+
console.log(`Value of 'a ^ b' after changing 'b' to '8':`);
|
|
1177
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1178
|
+
ignoreInitialValue: true,
|
|
1179
|
+
}).wait(() => {
|
|
1180
|
+
expressionContext.b = 8;
|
|
1181
|
+
});
|
|
1046
1182
|
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1183
|
+
console.log(`Final value of 'a ^ b':`);
|
|
1184
|
+
console.log(expression.value);
|
|
1185
|
+
} finally {
|
|
1186
|
+
// Always dispose of expressions after use.
|
|
1187
|
+
expression.dispose();
|
|
1188
|
+
}
|
|
1053
1189
|
})();
|
|
1054
|
-
|
|
1055
1190
|
```
|
|
1056
1191
|
|
|
1057
1192
|
### Conditional expression
|
|
@@ -1059,55 +1194,74 @@ export const run = (async () => {
|
|
|
1059
1194
|
```ts
|
|
1060
1195
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1061
1196
|
import {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1197
|
+
IExpressionFactory,
|
|
1198
|
+
RsXExpressionParserInjectionTokens,
|
|
1199
|
+
RsXExpressionParserModule,
|
|
1065
1200
|
} from '@rs-x/expression-parser';
|
|
1066
1201
|
|
|
1067
1202
|
// Load the expression parser module into the injection container
|
|
1068
1203
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1069
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1204
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1205
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1206
|
+
);
|
|
1070
1207
|
|
|
1071
1208
|
export const run = (async () => {
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1209
|
+
const expressionContext = {
|
|
1210
|
+
a: 1,
|
|
1211
|
+
b: 2,
|
|
1212
|
+
c: 100,
|
|
1213
|
+
d: 200,
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
const expression = expressionFactory.create(
|
|
1217
|
+
expressionContext,
|
|
1218
|
+
'a > b ? c : d',
|
|
1219
|
+
);
|
|
1220
|
+
|
|
1221
|
+
try {
|
|
1222
|
+
// Wait until the expression has been resolved (has a value)
|
|
1223
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1224
|
+
|
|
1225
|
+
console.log(`Initial value of 'a > b ? c : d':`);
|
|
1226
|
+
expression.changed.subscribe((change) => {
|
|
1227
|
+
console.log(change.value);
|
|
1228
|
+
});
|
|
1089
1229
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1230
|
+
console.log(`Value of 'a > b ? c : d' after changing d to '300':`);
|
|
1231
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1232
|
+
ignoreInitialValue: true,
|
|
1233
|
+
}).wait(() => {
|
|
1234
|
+
expressionContext.d = 300;
|
|
1235
|
+
});
|
|
1092
1236
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1237
|
+
console.log(`Value of 'a > b ? c : d' after changing 'a' to '3':`);
|
|
1238
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1239
|
+
ignoreInitialValue: true,
|
|
1240
|
+
}).wait(() => {
|
|
1241
|
+
expressionContext.a = 3;
|
|
1242
|
+
});
|
|
1095
1243
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1244
|
+
console.log(`Value of 'a > b ? c : d' after changing c to '2000':`);
|
|
1245
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1246
|
+
ignoreInitialValue: true,
|
|
1247
|
+
}).wait(() => {
|
|
1248
|
+
expressionContext.c = 2000;
|
|
1249
|
+
});
|
|
1098
1250
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1251
|
+
console.log(`Value of 'a > b ? c : d' after changing 'b' to '4':`);
|
|
1252
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1253
|
+
ignoreInitialValue: true,
|
|
1254
|
+
}).wait(() => {
|
|
1255
|
+
expressionContext.b = 4;
|
|
1256
|
+
});
|
|
1101
1257
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1258
|
+
console.log(`Final value of 'a > b ? c : d':`);
|
|
1259
|
+
console.log(expression.value);
|
|
1260
|
+
} finally {
|
|
1261
|
+
// Always dispose of expressions after use.
|
|
1262
|
+
expression.dispose();
|
|
1263
|
+
}
|
|
1108
1264
|
})();
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
1265
|
```
|
|
1112
1266
|
|
|
1113
1267
|
### Division expression
|
|
@@ -1115,47 +1269,55 @@ export const run = (async () => {
|
|
|
1115
1269
|
```ts
|
|
1116
1270
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1117
1271
|
import {
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1272
|
+
IExpressionFactory,
|
|
1273
|
+
RsXExpressionParserInjectionTokens,
|
|
1274
|
+
RsXExpressionParserModule,
|
|
1121
1275
|
} from '@rs-x/expression-parser';
|
|
1122
1276
|
|
|
1123
1277
|
// Load the expression parser module into the injection container
|
|
1124
1278
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1125
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1279
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1280
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1281
|
+
);
|
|
1126
1282
|
|
|
1127
1283
|
export const run = (async () => {
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1284
|
+
const expressionContext = {
|
|
1285
|
+
a: 20,
|
|
1286
|
+
b: 2,
|
|
1287
|
+
};
|
|
1132
1288
|
|
|
1133
|
-
|
|
1289
|
+
const expression = expressionFactory.create(expressionContext, 'a / b');
|
|
1134
1290
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1291
|
+
try {
|
|
1292
|
+
// Wait until the expression has been resolved (has a value)
|
|
1293
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1138
1294
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1295
|
+
console.log(`Initial value of 'a / b':`);
|
|
1296
|
+
expression.changed.subscribe((change) => {
|
|
1297
|
+
console.log(change.value);
|
|
1298
|
+
});
|
|
1143
1299
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1300
|
+
console.log(`Value of 'a / b' after changing 'a' to '10':`);
|
|
1301
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1302
|
+
ignoreInitialValue: true,
|
|
1303
|
+
}).wait(() => {
|
|
1304
|
+
expressionContext.a = 10;
|
|
1305
|
+
});
|
|
1146
1306
|
|
|
1147
|
-
|
|
1148
|
-
|
|
1307
|
+
console.log(`Value of 'a /b b' after changing 'b' to '2':`);
|
|
1308
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1309
|
+
ignoreInitialValue: true,
|
|
1310
|
+
}).wait(() => {
|
|
1311
|
+
expressionContext.b = 2;
|
|
1312
|
+
});
|
|
1149
1313
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1314
|
+
console.log(`Final value of 'a / b':`);
|
|
1315
|
+
console.log(expression.value);
|
|
1316
|
+
} finally {
|
|
1317
|
+
// Always dispose of expressions after use.
|
|
1318
|
+
expression.dispose();
|
|
1319
|
+
}
|
|
1156
1320
|
})();
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
1321
|
```
|
|
1160
1322
|
|
|
1161
1323
|
### Equality expression
|
|
@@ -1163,47 +1325,55 @@ export const run = (async () => {
|
|
|
1163
1325
|
```ts
|
|
1164
1326
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1165
1327
|
import {
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1328
|
+
IExpressionFactory,
|
|
1329
|
+
RsXExpressionParserInjectionTokens,
|
|
1330
|
+
RsXExpressionParserModule,
|
|
1169
1331
|
} from '@rs-x/expression-parser';
|
|
1170
1332
|
|
|
1171
1333
|
// Load the expression parser module into the injection container
|
|
1172
1334
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1173
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1335
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1336
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1337
|
+
);
|
|
1174
1338
|
|
|
1175
1339
|
export const run = (async () => {
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1340
|
+
const expressionContext = {
|
|
1341
|
+
a: 3,
|
|
1342
|
+
b: 2,
|
|
1343
|
+
};
|
|
1180
1344
|
|
|
1181
|
-
|
|
1345
|
+
const expression = expressionFactory.create(expressionContext, 'a == b');
|
|
1182
1346
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1347
|
+
try {
|
|
1348
|
+
// Wait until the expression has been resolved (has a value)
|
|
1349
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1186
1350
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1351
|
+
console.log(`Initial value of 'a == b':`);
|
|
1352
|
+
expression.changed.subscribe((change) => {
|
|
1353
|
+
console.log(change.value);
|
|
1354
|
+
});
|
|
1191
1355
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1356
|
+
console.log(`Value of 'a == b' after changing 'a' to '2':`);
|
|
1357
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1358
|
+
ignoreInitialValue: true,
|
|
1359
|
+
}).wait(() => {
|
|
1360
|
+
expressionContext.a = 2;
|
|
1361
|
+
});
|
|
1194
1362
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1363
|
+
console.log(`Value of 'a == b' after changing 'b' to '4':`);
|
|
1364
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1365
|
+
ignoreInitialValue: true,
|
|
1366
|
+
}).wait(() => {
|
|
1367
|
+
expressionContext.b = 4;
|
|
1368
|
+
});
|
|
1197
1369
|
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1370
|
+
console.log(`Final value of 'a == b':`);
|
|
1371
|
+
console.log(expression.value);
|
|
1372
|
+
} finally {
|
|
1373
|
+
// Always dispose of expressions after use.
|
|
1374
|
+
expression.dispose();
|
|
1375
|
+
}
|
|
1204
1376
|
})();
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
1377
|
```
|
|
1208
1378
|
|
|
1209
1379
|
### Exponentiation expression
|
|
@@ -1211,47 +1381,55 @@ export const run = (async () => {
|
|
|
1211
1381
|
```ts
|
|
1212
1382
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1213
1383
|
import {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1384
|
+
IExpressionFactory,
|
|
1385
|
+
RsXExpressionParserInjectionTokens,
|
|
1386
|
+
RsXExpressionParserModule,
|
|
1217
1387
|
} from '@rs-x/expression-parser';
|
|
1218
1388
|
|
|
1219
1389
|
// Load the expression parser module into the injection container
|
|
1220
1390
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1221
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1391
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1392
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1393
|
+
);
|
|
1222
1394
|
|
|
1223
1395
|
export const run = (async () => {
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1396
|
+
const expressionContext = {
|
|
1397
|
+
a: 2,
|
|
1398
|
+
b: 3,
|
|
1399
|
+
};
|
|
1228
1400
|
|
|
1229
|
-
|
|
1401
|
+
const expression = expressionFactory.create(expressionContext, 'a ** b');
|
|
1230
1402
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1403
|
+
try {
|
|
1404
|
+
// Wait until the expression has been resolved (has a value)
|
|
1405
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1234
1406
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1407
|
+
console.log(`Initial value of 'a ** b':`);
|
|
1408
|
+
expression.changed.subscribe((change) => {
|
|
1409
|
+
console.log(change.value);
|
|
1410
|
+
});
|
|
1239
1411
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1412
|
+
console.log(`Value of 'a ** b' after changing 'a' to '4':`);
|
|
1413
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1414
|
+
ignoreInitialValue: true,
|
|
1415
|
+
}).wait(() => {
|
|
1416
|
+
expressionContext.a = 4;
|
|
1417
|
+
});
|
|
1242
1418
|
|
|
1243
|
-
|
|
1244
|
-
|
|
1419
|
+
console.log(`Value of 'a ** b' after changing 'b' to '5':`);
|
|
1420
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1421
|
+
ignoreInitialValue: true,
|
|
1422
|
+
}).wait(() => {
|
|
1423
|
+
expressionContext.b = 5;
|
|
1424
|
+
});
|
|
1245
1425
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1426
|
+
console.log(`Final value of 'a ** b':`);
|
|
1427
|
+
console.log(expression.value);
|
|
1428
|
+
} finally {
|
|
1429
|
+
// Always dispose of expressions after use.
|
|
1430
|
+
expression.dispose();
|
|
1431
|
+
}
|
|
1252
1432
|
})();
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
1433
|
```
|
|
1256
1434
|
|
|
1257
1435
|
### Function expression
|
|
@@ -1259,49 +1437,61 @@ export const run = (async () => {
|
|
|
1259
1437
|
```ts
|
|
1260
1438
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1261
1439
|
import {
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1440
|
+
IExpressionFactory,
|
|
1441
|
+
RsXExpressionParserInjectionTokens,
|
|
1442
|
+
RsXExpressionParserModule,
|
|
1265
1443
|
} from '@rs-x/expression-parser';
|
|
1266
1444
|
|
|
1267
1445
|
// Load the expression parser module into the injection container
|
|
1268
1446
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1269
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1447
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1448
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1449
|
+
);
|
|
1270
1450
|
|
|
1271
1451
|
export const run = (async () => {
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1452
|
+
const expressionContext = {
|
|
1453
|
+
a: 2,
|
|
1454
|
+
b: 3,
|
|
1455
|
+
multiply(a: number, b: number) {
|
|
1456
|
+
return a * b;
|
|
1457
|
+
},
|
|
1458
|
+
};
|
|
1459
|
+
|
|
1460
|
+
const expression = expressionFactory.create(
|
|
1461
|
+
expressionContext,
|
|
1462
|
+
'multiply(a, b)',
|
|
1463
|
+
);
|
|
1464
|
+
|
|
1465
|
+
try {
|
|
1466
|
+
// Wait until the expression has been resolved (has a value)
|
|
1467
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1468
|
+
|
|
1469
|
+
console.log(`Initial value of 'multiply(a, b)'`);
|
|
1470
|
+
expression.changed.subscribe((change) => {
|
|
1471
|
+
console.log(change.value);
|
|
1472
|
+
});
|
|
1290
1473
|
|
|
1291
|
-
|
|
1292
|
-
|
|
1474
|
+
console.log(`Value of 'multiply(a, b)' after changing 'a' to '4':`);
|
|
1475
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1476
|
+
ignoreInitialValue: true,
|
|
1477
|
+
}).wait(() => {
|
|
1478
|
+
expressionContext.a = 4;
|
|
1479
|
+
});
|
|
1293
1480
|
|
|
1294
|
-
|
|
1295
|
-
|
|
1481
|
+
console.log(`Value of 'mutiply(a, b)' after changing 'b' to '5':`);
|
|
1482
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1483
|
+
ignoreInitialValue: true,
|
|
1484
|
+
}).wait(() => {
|
|
1485
|
+
expressionContext.b = 5;
|
|
1486
|
+
});
|
|
1296
1487
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1488
|
+
console.log(`Final value of 'multiply(a, b)':`);
|
|
1489
|
+
console.log(expression.value);
|
|
1490
|
+
} finally {
|
|
1491
|
+
// Always dispose of expressions after use.
|
|
1492
|
+
expression.dispose();
|
|
1493
|
+
}
|
|
1303
1494
|
})();
|
|
1304
|
-
|
|
1305
1495
|
```
|
|
1306
1496
|
|
|
1307
1497
|
### Greater than expression
|
|
@@ -1309,47 +1499,55 @@ export const run = (async () => {
|
|
|
1309
1499
|
```ts
|
|
1310
1500
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1311
1501
|
import {
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1502
|
+
IExpressionFactory,
|
|
1503
|
+
RsXExpressionParserInjectionTokens,
|
|
1504
|
+
RsXExpressionParserModule,
|
|
1315
1505
|
} from '@rs-x/expression-parser';
|
|
1316
1506
|
|
|
1317
1507
|
// Load the expression parser module into the injection container
|
|
1318
1508
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1319
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1509
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1510
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1511
|
+
);
|
|
1320
1512
|
|
|
1321
1513
|
export const run = (async () => {
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1514
|
+
const expressionContext = {
|
|
1515
|
+
a: 3,
|
|
1516
|
+
b: 2,
|
|
1517
|
+
};
|
|
1326
1518
|
|
|
1327
|
-
|
|
1519
|
+
const expression = expressionFactory.create(expressionContext, 'a > b');
|
|
1328
1520
|
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1521
|
+
try {
|
|
1522
|
+
// Wait until the expression has been resolved (has a value)
|
|
1523
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1332
1524
|
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1525
|
+
console.log(`Initial value of 'a > b':`);
|
|
1526
|
+
expression.changed.subscribe((change) => {
|
|
1527
|
+
console.log(change.value);
|
|
1528
|
+
});
|
|
1337
1529
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1530
|
+
console.log(`Value of 'a > b' after changing 'a' to '2':`);
|
|
1531
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1532
|
+
ignoreInitialValue: true,
|
|
1533
|
+
}).wait(() => {
|
|
1534
|
+
expressionContext.a = 2;
|
|
1535
|
+
});
|
|
1340
1536
|
|
|
1341
|
-
|
|
1342
|
-
|
|
1537
|
+
console.log(`Value of 'a > b' after changing 'b' to '1':`);
|
|
1538
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1539
|
+
ignoreInitialValue: true,
|
|
1540
|
+
}).wait(() => {
|
|
1541
|
+
expressionContext.b = 1;
|
|
1542
|
+
});
|
|
1343
1543
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1544
|
+
console.log(`Final value of 'a > b':`);
|
|
1545
|
+
console.log(expression.value);
|
|
1546
|
+
} finally {
|
|
1547
|
+
// Always dispose of expressions after use.
|
|
1548
|
+
expression.dispose();
|
|
1549
|
+
}
|
|
1350
1550
|
})();
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
1551
|
```
|
|
1354
1552
|
|
|
1355
1553
|
### Greater than or equal expression
|
|
@@ -1357,97 +1555,121 @@ export const run = (async () => {
|
|
|
1357
1555
|
```ts
|
|
1358
1556
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1359
1557
|
import {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1558
|
+
IExpressionFactory,
|
|
1559
|
+
RsXExpressionParserInjectionTokens,
|
|
1560
|
+
RsXExpressionParserModule,
|
|
1363
1561
|
} from '@rs-x/expression-parser';
|
|
1364
1562
|
|
|
1365
1563
|
// Load the expression parser module into the injection container
|
|
1366
1564
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1367
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1565
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1566
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1567
|
+
);
|
|
1368
1568
|
|
|
1369
1569
|
export const run = (async () => {
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1570
|
+
const expressionContext = {
|
|
1571
|
+
a: 3,
|
|
1572
|
+
b: 2,
|
|
1573
|
+
};
|
|
1374
1574
|
|
|
1375
|
-
|
|
1575
|
+
const expression = expressionFactory.create(expressionContext, 'a >= b');
|
|
1376
1576
|
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1577
|
+
try {
|
|
1578
|
+
// Wait until the expression has been resolved (has a value)
|
|
1579
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1380
1580
|
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1581
|
+
console.log(`Initial value of 'a >= b':`);
|
|
1582
|
+
expression.changed.subscribe((change) => {
|
|
1583
|
+
console.log(change.value);
|
|
1584
|
+
});
|
|
1385
1585
|
|
|
1386
|
-
|
|
1387
|
-
|
|
1586
|
+
console.log(`Value of 'a >= b' after changing 'a' to '1':`);
|
|
1587
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1588
|
+
ignoreInitialValue: true,
|
|
1589
|
+
}).wait(() => {
|
|
1590
|
+
expressionContext.a = 1;
|
|
1591
|
+
});
|
|
1388
1592
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1593
|
+
console.log(`Value of 'a >= b' after changing 'b' to '0':`);
|
|
1594
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1595
|
+
ignoreInitialValue: true,
|
|
1596
|
+
}).wait(() => {
|
|
1597
|
+
expressionContext.b = 0;
|
|
1598
|
+
});
|
|
1391
1599
|
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1600
|
+
console.log(`Final value of 'a >= b':`);
|
|
1601
|
+
console.log(expression.value);
|
|
1602
|
+
} finally {
|
|
1603
|
+
// Always dispose of expressions after use.
|
|
1604
|
+
expression.dispose();
|
|
1605
|
+
}
|
|
1398
1606
|
})();
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
1607
|
```
|
|
1402
1608
|
|
|
1403
1609
|
### In expression
|
|
1404
1610
|
|
|
1405
1611
|
```ts
|
|
1406
|
-
import { emptyFunction, InjectionContainer, Type, WaitForEvent } from '@rs-x/core';
|
|
1407
1612
|
import {
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1613
|
+
emptyFunction,
|
|
1614
|
+
InjectionContainer,
|
|
1615
|
+
Type,
|
|
1616
|
+
WaitForEvent,
|
|
1617
|
+
} from '@rs-x/core';
|
|
1618
|
+
import {
|
|
1619
|
+
IExpressionFactory,
|
|
1620
|
+
RsXExpressionParserInjectionTokens,
|
|
1621
|
+
RsXExpressionParserModule,
|
|
1411
1622
|
} from '@rs-x/expression-parser';
|
|
1412
1623
|
|
|
1413
1624
|
// Load the expression parser module into the injection container
|
|
1414
1625
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1415
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1626
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1627
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1628
|
+
);
|
|
1416
1629
|
|
|
1417
1630
|
export const run = (async () => {
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1631
|
+
const expressionContext = {
|
|
1632
|
+
propertyName: 'hello',
|
|
1633
|
+
b: {
|
|
1634
|
+
hello: 'hi',
|
|
1635
|
+
},
|
|
1636
|
+
};
|
|
1637
|
+
|
|
1638
|
+
const expression = expressionFactory.create(
|
|
1639
|
+
expressionContext,
|
|
1640
|
+
'propertyName in b',
|
|
1641
|
+
);
|
|
1642
|
+
|
|
1643
|
+
try {
|
|
1644
|
+
// Wait until the expression has been resolved (has a value)
|
|
1645
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1646
|
+
|
|
1647
|
+
console.log(`Initial value of 'propertyName in b':`);
|
|
1648
|
+
expression.changed.subscribe((change) => {
|
|
1649
|
+
console.log(change.value);
|
|
1650
|
+
});
|
|
1435
1651
|
|
|
1436
|
-
|
|
1437
|
-
|
|
1652
|
+
console.log(`Value of 'propertyName in b' after changing 'a' to 'x':`);
|
|
1653
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1654
|
+
ignoreInitialValue: true,
|
|
1655
|
+
}).wait(() => {
|
|
1656
|
+
expressionContext.propertyName = 'x';
|
|
1657
|
+
});
|
|
1438
1658
|
|
|
1439
|
-
|
|
1440
|
-
|
|
1659
|
+
console.log(`Value of 'propertyName in b' after changing 'b' to '{x: 1}':`);
|
|
1660
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1661
|
+
ignoreInitialValue: true,
|
|
1662
|
+
}).wait(() => {
|
|
1663
|
+
expressionContext.b = Type.cast({ x: 1 });
|
|
1664
|
+
});
|
|
1441
1665
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1666
|
+
console.log(`Final value of 'propertyName in b':`);
|
|
1667
|
+
console.log(expression.value);
|
|
1668
|
+
} finally {
|
|
1669
|
+
// Always dispose of expressions after use.
|
|
1670
|
+
expression.dispose();
|
|
1671
|
+
}
|
|
1448
1672
|
})();
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
1673
|
```
|
|
1452
1674
|
|
|
1453
1675
|
### Inequality expression
|
|
@@ -1455,95 +1677,123 @@ export const run = (async () => {
|
|
|
1455
1677
|
```ts
|
|
1456
1678
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1457
1679
|
import {
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1680
|
+
IExpressionFactory,
|
|
1681
|
+
RsXExpressionParserInjectionTokens,
|
|
1682
|
+
RsXExpressionParserModule,
|
|
1461
1683
|
} from '@rs-x/expression-parser';
|
|
1462
1684
|
|
|
1463
1685
|
// Load the expression parser module into the injection container
|
|
1464
1686
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1465
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1687
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1688
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1689
|
+
);
|
|
1466
1690
|
|
|
1467
1691
|
export const run = (async () => {
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1692
|
+
const expressionContext = {
|
|
1693
|
+
a: 1,
|
|
1694
|
+
b: 2,
|
|
1695
|
+
};
|
|
1472
1696
|
|
|
1473
|
-
|
|
1697
|
+
const expression = expressionFactory.create(expressionContext, 'a != b');
|
|
1474
1698
|
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1699
|
+
try {
|
|
1700
|
+
// Wait until the expression has been resolved (has a value)
|
|
1701
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1478
1702
|
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1703
|
+
console.log(`Initial value of 'a != b':`);
|
|
1704
|
+
expression.changed.subscribe((change) => {
|
|
1705
|
+
console.log(change.value);
|
|
1706
|
+
});
|
|
1483
1707
|
|
|
1484
|
-
|
|
1485
|
-
|
|
1708
|
+
console.log(`Value of 'a != b' after changing 'a' to '2':`);
|
|
1709
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1710
|
+
ignoreInitialValue: true,
|
|
1711
|
+
}).wait(() => {
|
|
1712
|
+
expressionContext.a = 2;
|
|
1713
|
+
});
|
|
1486
1714
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1715
|
+
console.log(`Value of 'a != b' after changing 'b' to '2':`);
|
|
1716
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1717
|
+
ignoreInitialValue: true,
|
|
1718
|
+
}).wait(() => {
|
|
1719
|
+
expressionContext.b = 2;
|
|
1720
|
+
});
|
|
1489
1721
|
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1722
|
+
console.log(`Final value of 'a != b':`);
|
|
1723
|
+
console.log(expression.value);
|
|
1724
|
+
} finally {
|
|
1725
|
+
// Always dispose of expressions after use.
|
|
1726
|
+
expression.dispose();
|
|
1727
|
+
}
|
|
1496
1728
|
})();
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
1729
|
```
|
|
1500
1730
|
|
|
1501
1731
|
### Instanceof expression
|
|
1502
1732
|
|
|
1503
1733
|
```ts
|
|
1504
|
-
import { emptyFunction, InjectionContainer, Type, WaitForEvent } from '@rs-x/core';
|
|
1505
1734
|
import {
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1735
|
+
emptyFunction,
|
|
1736
|
+
InjectionContainer,
|
|
1737
|
+
Type,
|
|
1738
|
+
WaitForEvent,
|
|
1739
|
+
} from '@rs-x/core';
|
|
1740
|
+
import {
|
|
1741
|
+
IExpressionFactory,
|
|
1742
|
+
RsXExpressionParserInjectionTokens,
|
|
1743
|
+
RsXExpressionParserModule,
|
|
1509
1744
|
} from '@rs-x/expression-parser';
|
|
1510
1745
|
|
|
1511
1746
|
// Load the expression parser module into the injection container
|
|
1512
1747
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1513
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1748
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1749
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1750
|
+
);
|
|
1514
1751
|
|
|
1515
1752
|
export const run = (async () => {
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1753
|
+
const expressionContext = {
|
|
1754
|
+
type: Date,
|
|
1755
|
+
a: new Date(),
|
|
1756
|
+
};
|
|
1757
|
+
|
|
1758
|
+
const expression = expressionFactory.create(
|
|
1759
|
+
expressionContext,
|
|
1760
|
+
'a instanceof type',
|
|
1761
|
+
);
|
|
1762
|
+
|
|
1763
|
+
try {
|
|
1764
|
+
// Wait until the expression has been resolved (has a value)
|
|
1765
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1766
|
+
|
|
1767
|
+
console.log(`Initial value of 'a instanceof type':`);
|
|
1768
|
+
expression.changed.subscribe((change) => {
|
|
1769
|
+
console.log(change.value);
|
|
1770
|
+
});
|
|
1531
1771
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1772
|
+
console.log(
|
|
1773
|
+
`Value of 'a instanceof type' after changing 'a' to 'new Number(2)':`,
|
|
1774
|
+
);
|
|
1775
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1776
|
+
ignoreInitialValue: true,
|
|
1777
|
+
}).wait(() => {
|
|
1778
|
+
expressionContext.a = Type.cast(new Number(2));
|
|
1779
|
+
});
|
|
1534
1780
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1781
|
+
console.log(
|
|
1782
|
+
`Value of 'a instanceof type' after changing 'type' to 'Number':`,
|
|
1783
|
+
);
|
|
1784
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1785
|
+
ignoreInitialValue: true,
|
|
1786
|
+
}).wait(() => {
|
|
1787
|
+
expressionContext.type = Type.cast(Number);
|
|
1788
|
+
});
|
|
1537
1789
|
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1790
|
+
console.log(`Final value of 'a instanceof type':`);
|
|
1791
|
+
console.log(expression.value);
|
|
1792
|
+
} finally {
|
|
1793
|
+
// Always dispose of expressions after use.
|
|
1794
|
+
expression.dispose();
|
|
1795
|
+
}
|
|
1544
1796
|
})();
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
1797
|
```
|
|
1548
1798
|
|
|
1549
1799
|
### Less than expression
|
|
@@ -1551,47 +1801,55 @@ export const run = (async () => {
|
|
|
1551
1801
|
```ts
|
|
1552
1802
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1553
1803
|
import {
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1804
|
+
IExpressionFactory,
|
|
1805
|
+
RsXExpressionParserInjectionTokens,
|
|
1806
|
+
RsXExpressionParserModule,
|
|
1557
1807
|
} from '@rs-x/expression-parser';
|
|
1558
1808
|
|
|
1559
1809
|
// Load the expression parser module into the injection container
|
|
1560
1810
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1561
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1811
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1812
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1813
|
+
);
|
|
1562
1814
|
|
|
1563
1815
|
export const run = (async () => {
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1816
|
+
const expressionContext = {
|
|
1817
|
+
a: 2,
|
|
1818
|
+
b: 3,
|
|
1819
|
+
};
|
|
1568
1820
|
|
|
1569
|
-
|
|
1821
|
+
const expression = expressionFactory.create(expressionContext, 'a < b');
|
|
1570
1822
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1823
|
+
try {
|
|
1824
|
+
// Wait until the expression has been resolved (has a value)
|
|
1825
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1574
1826
|
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1827
|
+
console.log(`Initial value of 'a < b':`);
|
|
1828
|
+
expression.changed.subscribe((change) => {
|
|
1829
|
+
console.log(change.value);
|
|
1830
|
+
});
|
|
1579
1831
|
|
|
1580
|
-
|
|
1581
|
-
|
|
1832
|
+
console.log(`Value of 'a < b' after changing 'a' to '3':`);
|
|
1833
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1834
|
+
ignoreInitialValue: true,
|
|
1835
|
+
}).wait(() => {
|
|
1836
|
+
expressionContext.a = 3;
|
|
1837
|
+
});
|
|
1582
1838
|
|
|
1583
|
-
|
|
1584
|
-
|
|
1839
|
+
console.log(`Value of 'a < b' after changing 'b' to '4':`);
|
|
1840
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1841
|
+
ignoreInitialValue: true,
|
|
1842
|
+
}).wait(() => {
|
|
1843
|
+
expressionContext.b = 4;
|
|
1844
|
+
});
|
|
1585
1845
|
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1846
|
+
console.log(`Final value of 'a < b':`);
|
|
1847
|
+
console.log(expression.value);
|
|
1848
|
+
} finally {
|
|
1849
|
+
// Always dispose of expressions after use.
|
|
1850
|
+
expression.dispose();
|
|
1851
|
+
}
|
|
1592
1852
|
})();
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
1853
|
```
|
|
1596
1854
|
|
|
1597
1855
|
### Less than or equal expression
|
|
@@ -1599,47 +1857,55 @@ export const run = (async () => {
|
|
|
1599
1857
|
```ts
|
|
1600
1858
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1601
1859
|
import {
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1860
|
+
IExpressionFactory,
|
|
1861
|
+
RsXExpressionParserInjectionTokens,
|
|
1862
|
+
RsXExpressionParserModule,
|
|
1605
1863
|
} from '@rs-x/expression-parser';
|
|
1606
1864
|
|
|
1607
1865
|
// Load the expression parser module into the injection container
|
|
1608
1866
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1609
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1867
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1868
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1869
|
+
);
|
|
1610
1870
|
|
|
1611
1871
|
export const run = (async () => {
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1872
|
+
const expressionContext = {
|
|
1873
|
+
a: 2,
|
|
1874
|
+
b: 3,
|
|
1875
|
+
};
|
|
1616
1876
|
|
|
1617
|
-
|
|
1877
|
+
const expression = expressionFactory.create(expressionContext, 'a <= b');
|
|
1618
1878
|
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1879
|
+
try {
|
|
1880
|
+
// Wait until the expression has been resolved (has a value)
|
|
1881
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1622
1882
|
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1883
|
+
console.log(`Initial value of 'a <= b':`);
|
|
1884
|
+
expression.changed.subscribe((change) => {
|
|
1885
|
+
console.log(change.value);
|
|
1886
|
+
});
|
|
1627
1887
|
|
|
1628
|
-
|
|
1629
|
-
|
|
1888
|
+
console.log(`Value of 'a <= b' after changing 'a' to '4':`);
|
|
1889
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1890
|
+
ignoreInitialValue: true,
|
|
1891
|
+
}).wait(() => {
|
|
1892
|
+
expressionContext.a = 4;
|
|
1893
|
+
});
|
|
1630
1894
|
|
|
1631
|
-
|
|
1632
|
-
|
|
1895
|
+
console.log(`Value of 'a < b' after changing 'b' to '4':`);
|
|
1896
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1897
|
+
ignoreInitialValue: true,
|
|
1898
|
+
}).wait(() => {
|
|
1899
|
+
expressionContext.b = 4;
|
|
1900
|
+
});
|
|
1633
1901
|
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1902
|
+
console.log(`Final value of 'a <= b':`);
|
|
1903
|
+
console.log(expression.value);
|
|
1904
|
+
} finally {
|
|
1905
|
+
// Always dispose of expressions after use.
|
|
1906
|
+
expression.dispose();
|
|
1907
|
+
}
|
|
1640
1908
|
})();
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
1909
|
```
|
|
1644
1910
|
|
|
1645
1911
|
### Logical and expression
|
|
@@ -1647,46 +1913,55 @@ export const run = (async () => {
|
|
|
1647
1913
|
```ts
|
|
1648
1914
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1649
1915
|
import {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1916
|
+
IExpressionFactory,
|
|
1917
|
+
RsXExpressionParserInjectionTokens,
|
|
1918
|
+
RsXExpressionParserModule,
|
|
1653
1919
|
} from '@rs-x/expression-parser';
|
|
1654
1920
|
|
|
1655
1921
|
// Load the expression parser module into the injection container
|
|
1656
1922
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1657
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1923
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1924
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1925
|
+
);
|
|
1658
1926
|
|
|
1659
1927
|
export const run = (async () => {
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1928
|
+
const expressionContext = {
|
|
1929
|
+
a: false,
|
|
1930
|
+
b: true,
|
|
1931
|
+
};
|
|
1664
1932
|
|
|
1665
|
-
|
|
1933
|
+
const expression = expressionFactory.create(expressionContext, 'a && b');
|
|
1666
1934
|
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1935
|
+
try {
|
|
1936
|
+
// Wait until the expression has been resolved (has a value)
|
|
1937
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1670
1938
|
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1939
|
+
console.log(`Initial value of 'a && b':`);
|
|
1940
|
+
expression.changed.subscribe((change) => {
|
|
1941
|
+
console.log(change.value);
|
|
1942
|
+
});
|
|
1675
1943
|
|
|
1676
|
-
|
|
1677
|
-
|
|
1944
|
+
console.log(`Value of 'a && b' after changing 'a' to 'true':`);
|
|
1945
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1946
|
+
ignoreInitialValue: true,
|
|
1947
|
+
}).wait(() => {
|
|
1948
|
+
expressionContext.a = true;
|
|
1949
|
+
});
|
|
1678
1950
|
|
|
1679
|
-
|
|
1680
|
-
|
|
1951
|
+
console.log(`Value of 'a && b' after changing 'b' to 'false':`);
|
|
1952
|
+
await new WaitForEvent(expression, 'changed', {
|
|
1953
|
+
ignoreInitialValue: true,
|
|
1954
|
+
}).wait(() => {
|
|
1955
|
+
expressionContext.b = false;
|
|
1956
|
+
});
|
|
1681
1957
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1958
|
+
console.log(`Final value of 'a && b':`);
|
|
1959
|
+
console.log(expression.value);
|
|
1960
|
+
} finally {
|
|
1961
|
+
// Always dispose of expressions after use.
|
|
1962
|
+
expression.dispose();
|
|
1963
|
+
}
|
|
1688
1964
|
})();
|
|
1689
|
-
|
|
1690
1965
|
```
|
|
1691
1966
|
|
|
1692
1967
|
### Logical not expression
|
|
@@ -1694,40 +1969,46 @@ export const run = (async () => {
|
|
|
1694
1969
|
```ts
|
|
1695
1970
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1696
1971
|
import {
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1972
|
+
IExpressionFactory,
|
|
1973
|
+
RsXExpressionParserInjectionTokens,
|
|
1974
|
+
RsXExpressionParserModule,
|
|
1700
1975
|
} from '@rs-x/expression-parser';
|
|
1701
1976
|
|
|
1702
1977
|
// Load the expression parser module into the injection container
|
|
1703
1978
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1704
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1979
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
1980
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
1981
|
+
);
|
|
1705
1982
|
|
|
1706
1983
|
export const run = (async () => {
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1984
|
+
const expressionContext = {
|
|
1985
|
+
a: false,
|
|
1986
|
+
};
|
|
1710
1987
|
|
|
1711
|
-
|
|
1988
|
+
const expression = expressionFactory.create(expressionContext, '!a');
|
|
1712
1989
|
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1990
|
+
try {
|
|
1991
|
+
// Wait until the expression has been resolved (has a value)
|
|
1992
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1716
1993
|
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1994
|
+
console.log(`Initial value of '!a':`);
|
|
1995
|
+
expression.changed.subscribe((change) => {
|
|
1996
|
+
console.log(change.value);
|
|
1997
|
+
});
|
|
1721
1998
|
|
|
1722
|
-
|
|
1723
|
-
|
|
1999
|
+
console.log(`Value of !a' after changing 'a' to 'true':`);
|
|
2000
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2001
|
+
ignoreInitialValue: true,
|
|
2002
|
+
}).wait(() => {
|
|
2003
|
+
expressionContext.a = true;
|
|
2004
|
+
});
|
|
1724
2005
|
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
2006
|
+
console.log(`Final value of '!a':`);
|
|
2007
|
+
console.log(expression.value);
|
|
2008
|
+
} finally {
|
|
2009
|
+
// Always dispose of expressions after use.
|
|
2010
|
+
expression.dispose();
|
|
2011
|
+
}
|
|
1731
2012
|
})();
|
|
1732
2013
|
```
|
|
1733
2014
|
|
|
@@ -1736,537 +2017,693 @@ export const run = (async () => {
|
|
|
1736
2017
|
```ts
|
|
1737
2018
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
1738
2019
|
import {
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
2020
|
+
IExpressionFactory,
|
|
2021
|
+
RsXExpressionParserInjectionTokens,
|
|
2022
|
+
RsXExpressionParserModule,
|
|
1742
2023
|
} from '@rs-x/expression-parser';
|
|
1743
2024
|
|
|
1744
2025
|
// Load the expression parser module into the injection container
|
|
1745
2026
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
1746
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2027
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2028
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2029
|
+
);
|
|
1747
2030
|
|
|
1748
2031
|
export const run = (async () => {
|
|
2032
|
+
const expressionContext = {
|
|
2033
|
+
a: true,
|
|
2034
|
+
b: false,
|
|
2035
|
+
};
|
|
2036
|
+
|
|
2037
|
+
const expression = expressionFactory.create(expressionContext, 'a || b');
|
|
2038
|
+
|
|
2039
|
+
try {
|
|
2040
|
+
// Wait until the expression has been resolved (has a value)
|
|
2041
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2042
|
+
|
|
2043
|
+
console.log(`Initial value of 'a || b':`);
|
|
2044
|
+
expression.changed.subscribe((change) => {
|
|
2045
|
+
console.log(change.value);
|
|
2046
|
+
});
|
|
2047
|
+
|
|
2048
|
+
console.log(`Value of 'a || b' after changing 'a' to 'false':`);
|
|
2049
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2050
|
+
ignoreInitialValue: true,
|
|
2051
|
+
}).wait(() => {
|
|
2052
|
+
expressionContext.a = false;
|
|
2053
|
+
});
|
|
2054
|
+
|
|
2055
|
+
console.log(`Value of 'a || b' after changing 'b' to 'true':`);
|
|
2056
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2057
|
+
ignoreInitialValue: true,
|
|
2058
|
+
}).wait(() => {
|
|
2059
|
+
expressionContext.b = true;
|
|
2060
|
+
});
|
|
2061
|
+
|
|
2062
|
+
console.log(`Final value of 'a || b':`);
|
|
2063
|
+
console.log(expression.value);
|
|
2064
|
+
} finally {
|
|
2065
|
+
// Always dispose of expressions after use.
|
|
2066
|
+
expression.dispose();
|
|
2067
|
+
}
|
|
2068
|
+
})();
|
|
2069
|
+
```
|
|
2070
|
+
|
|
2071
|
+
### Member expression
|
|
2072
|
+
|
|
2073
|
+
- Member expression
|
|
2074
|
+
|
|
2075
|
+
```ts
|
|
2076
|
+
import {
|
|
2077
|
+
emptyFunction,
|
|
2078
|
+
InjectionContainer,
|
|
2079
|
+
printValue,
|
|
2080
|
+
WaitForEvent,
|
|
2081
|
+
} from '@rs-x/core';
|
|
2082
|
+
import {
|
|
2083
|
+
IExpressionFactory,
|
|
2084
|
+
RsXExpressionParserInjectionTokens,
|
|
2085
|
+
RsXExpressionParserModule,
|
|
2086
|
+
} from '@rs-x/expression-parser';
|
|
2087
|
+
|
|
2088
|
+
// Load the expression parser module into the injection container
|
|
2089
|
+
InjectionContainer.load(RsXExpressionParserModule);
|
|
2090
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2091
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2092
|
+
);
|
|
2093
|
+
|
|
2094
|
+
export const run = (async () => {
|
|
1749
2095
|
const expressionContext = {
|
|
1750
|
-
|
|
1751
|
-
b:
|
|
2096
|
+
a: {
|
|
2097
|
+
b: {
|
|
2098
|
+
c: 10,
|
|
2099
|
+
},
|
|
2100
|
+
},
|
|
1752
2101
|
};
|
|
1753
2102
|
|
|
1754
|
-
const expression = expressionFactory.create(expressionContext, 'a
|
|
2103
|
+
const expression = expressionFactory.create(expressionContext, 'a.b.c');
|
|
1755
2104
|
|
|
1756
2105
|
try {
|
|
1757
|
-
|
|
1758
|
-
|
|
2106
|
+
// Wait until the expression has been resolved (has a value)
|
|
2107
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2108
|
+
|
|
2109
|
+
console.log(`Initial value of 'a.b.c':`);
|
|
2110
|
+
expression.changed.subscribe((change) => {
|
|
2111
|
+
printValue(change.value);
|
|
2112
|
+
});
|
|
2113
|
+
|
|
2114
|
+
console.log(`Value of 'a.b.c' after changing 'a' to '{b : {c: 20}}':`);
|
|
2115
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2116
|
+
ignoreInitialValue: true,
|
|
2117
|
+
}).wait(() => {
|
|
2118
|
+
expressionContext.a = { b: { c: 20 } };
|
|
2119
|
+
});
|
|
2120
|
+
|
|
2121
|
+
console.log(`Value of 'a.b.c' after changing 'b' to '{c: 30}':`);
|
|
2122
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2123
|
+
ignoreInitialValue: true,
|
|
2124
|
+
}).wait(() => {
|
|
2125
|
+
expressionContext.a.b = { c: 30 };
|
|
2126
|
+
});
|
|
2127
|
+
|
|
2128
|
+
console.log(`Value of 'a.b.c' after changing c to '40':`);
|
|
2129
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2130
|
+
ignoreInitialValue: true,
|
|
2131
|
+
}).wait(() => {
|
|
2132
|
+
expressionContext.a.b.c = 40;
|
|
2133
|
+
});
|
|
2134
|
+
|
|
2135
|
+
console.log(`Final value of 'a.b.c':`);
|
|
2136
|
+
printValue(expression.value);
|
|
2137
|
+
} finally {
|
|
2138
|
+
// Always dispose of expressions after use.
|
|
2139
|
+
expression.dispose();
|
|
2140
|
+
}
|
|
2141
|
+
})();
|
|
2142
|
+
```
|
|
2143
|
+
|
|
2144
|
+
- Member expression with array
|
|
2145
|
+
|
|
2146
|
+
```ts
|
|
2147
|
+
import {
|
|
2148
|
+
emptyFunction,
|
|
2149
|
+
InjectionContainer,
|
|
2150
|
+
printValue,
|
|
2151
|
+
WaitForEvent,
|
|
2152
|
+
} from '@rs-x/core';
|
|
2153
|
+
import {
|
|
2154
|
+
IExpressionFactory,
|
|
2155
|
+
RsXExpressionParserInjectionTokens,
|
|
2156
|
+
RsXExpressionParserModule,
|
|
2157
|
+
} from '@rs-x/expression-parser';
|
|
1759
2158
|
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
2159
|
+
// Load the expression parser module into the injection container
|
|
2160
|
+
InjectionContainer.load(RsXExpressionParserModule);
|
|
2161
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2162
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2163
|
+
);
|
|
1764
2164
|
|
|
1765
|
-
|
|
1766
|
-
|
|
2165
|
+
export const run = (async () => {
|
|
2166
|
+
const expressionContext = {
|
|
2167
|
+
a: {
|
|
2168
|
+
b: [
|
|
2169
|
+
{
|
|
2170
|
+
c: {
|
|
2171
|
+
d: 10,
|
|
2172
|
+
},
|
|
2173
|
+
},
|
|
2174
|
+
{
|
|
2175
|
+
c: {
|
|
2176
|
+
d: 11,
|
|
2177
|
+
},
|
|
2178
|
+
},
|
|
2179
|
+
],
|
|
2180
|
+
},
|
|
2181
|
+
x: { y: 1 },
|
|
2182
|
+
};
|
|
1767
2183
|
|
|
1768
|
-
|
|
1769
|
-
|
|
2184
|
+
const expression = expressionFactory.create(
|
|
2185
|
+
expressionContext,
|
|
2186
|
+
'a.b[1].c.d',
|
|
2187
|
+
);
|
|
1770
2188
|
|
|
1771
|
-
|
|
1772
|
-
|
|
2189
|
+
try {
|
|
2190
|
+
// Wait until the expression has been resolved (has a value)
|
|
2191
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2192
|
+
|
|
2193
|
+
console.log(`Initial value of 'a.b[1].c.d':`);
|
|
2194
|
+
expression.changed.subscribe((change) => {
|
|
2195
|
+
printValue(change.value);
|
|
2196
|
+
});
|
|
2197
|
+
|
|
2198
|
+
console.log(
|
|
2199
|
+
`Value of 'a.b.c' after changing 'a' to '{b: [{ c: { d: 100}},{ c: { d: 110}}}':`,
|
|
2200
|
+
);
|
|
2201
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2202
|
+
ignoreInitialValue: true,
|
|
2203
|
+
}).wait(() => {
|
|
2204
|
+
expressionContext.a = {
|
|
2205
|
+
b: [
|
|
2206
|
+
{
|
|
2207
|
+
c: {
|
|
2208
|
+
d: 100,
|
|
2209
|
+
},
|
|
2210
|
+
},
|
|
2211
|
+
{
|
|
2212
|
+
c: {
|
|
2213
|
+
d: 110,
|
|
2214
|
+
},
|
|
2215
|
+
},
|
|
2216
|
+
],
|
|
2217
|
+
};
|
|
2218
|
+
});
|
|
2219
|
+
|
|
2220
|
+
console.log(
|
|
2221
|
+
`Value of 'a.b[1].c.d' after changing b[1] to '{ c: { d: 120}}':`,
|
|
2222
|
+
);
|
|
2223
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2224
|
+
ignoreInitialValue: true,
|
|
2225
|
+
}).wait(() => {
|
|
2226
|
+
expressionContext.a.b[1] = {
|
|
2227
|
+
c: {
|
|
2228
|
+
d: 120,
|
|
2229
|
+
},
|
|
2230
|
+
};
|
|
2231
|
+
});
|
|
2232
|
+
|
|
2233
|
+
console.log(`Value of 'a.b[1].c.d' after changing b[1].c to '{d: 220}':`);
|
|
2234
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2235
|
+
ignoreInitialValue: true,
|
|
2236
|
+
}).wait(() => {
|
|
2237
|
+
expressionContext.a.b[1].c = { d: 220 };
|
|
2238
|
+
});
|
|
2239
|
+
|
|
2240
|
+
console.log(`Value of 'a.b[1].c.d' after changing b[1].c.d to '330':`);
|
|
2241
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2242
|
+
ignoreInitialValue: true,
|
|
2243
|
+
}).wait(() => {
|
|
2244
|
+
expressionContext.a.b[1].c.d = 330;
|
|
2245
|
+
});
|
|
2246
|
+
|
|
2247
|
+
console.log(`Final value of 'a.b[1].c.d':`);
|
|
2248
|
+
printValue(expression.value);
|
|
1773
2249
|
} finally {
|
|
1774
|
-
|
|
1775
|
-
|
|
2250
|
+
// Always dispose of expressions after use.
|
|
2251
|
+
expression.dispose();
|
|
1776
2252
|
}
|
|
1777
|
-
})();
|
|
2253
|
+
})();
|
|
2254
|
+
```
|
|
2255
|
+
|
|
2256
|
+
- Member expression with map
|
|
2257
|
+
|
|
2258
|
+
```ts
|
|
2259
|
+
import {
|
|
2260
|
+
emptyFunction,
|
|
2261
|
+
InjectionContainer,
|
|
2262
|
+
printValue,
|
|
2263
|
+
WaitForEvent,
|
|
2264
|
+
} from '@rs-x/core';
|
|
2265
|
+
import {
|
|
2266
|
+
IExpressionFactory,
|
|
2267
|
+
RsXExpressionParserInjectionTokens,
|
|
2268
|
+
RsXExpressionParserModule,
|
|
2269
|
+
} from '@rs-x/expression-parser';
|
|
1778
2270
|
|
|
2271
|
+
// Load the expression parser module into the injection container
|
|
2272
|
+
InjectionContainer.load(RsXExpressionParserModule);
|
|
2273
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2274
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2275
|
+
);
|
|
1779
2276
|
|
|
1780
|
-
|
|
2277
|
+
export const run = (async () => {
|
|
2278
|
+
const expressionContext = {
|
|
2279
|
+
a: {
|
|
2280
|
+
b: new Map([
|
|
2281
|
+
['a', { c: { d: 1 } }],
|
|
2282
|
+
['b', { c: { d: 2 } }],
|
|
2283
|
+
]),
|
|
2284
|
+
},
|
|
2285
|
+
};
|
|
1781
2286
|
|
|
1782
|
-
|
|
2287
|
+
const expression = expressionFactory.create(
|
|
2288
|
+
expressionContext,
|
|
2289
|
+
`a.b['b'].c.d`,
|
|
2290
|
+
);
|
|
1783
2291
|
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
2292
|
+
try {
|
|
2293
|
+
// Wait until the expression has been resolved (has a value)
|
|
2294
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2295
|
+
|
|
2296
|
+
console.log(`Initial value of 'a.b['b'].c.d':`);
|
|
2297
|
+
expression.changed.subscribe((change) => {
|
|
2298
|
+
printValue(change.value);
|
|
2299
|
+
});
|
|
2300
|
+
|
|
2301
|
+
console.log(
|
|
2302
|
+
`Value of 'a.b['b'].c.d' after changing 'a' to '{ b: new Map([['a', { c: { d: 11 } }], ['b', { c: { d: 21 } }]]) }':`,
|
|
2303
|
+
);
|
|
2304
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2305
|
+
ignoreInitialValue: true,
|
|
2306
|
+
}).wait(() => {
|
|
2307
|
+
expressionContext.a = {
|
|
2308
|
+
b: new Map([
|
|
2309
|
+
['a', { c: { d: 11 } }],
|
|
2310
|
+
['b', { c: { d: 21 } }],
|
|
2311
|
+
]),
|
|
1804
2312
|
};
|
|
2313
|
+
});
|
|
2314
|
+
|
|
2315
|
+
console.log(
|
|
2316
|
+
`Value of 'a.b['b'].c.d' after changing b['b'] to '{ c: { d: 120 } }':`,
|
|
2317
|
+
);
|
|
2318
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2319
|
+
ignoreInitialValue: true,
|
|
2320
|
+
}).wait(() => {
|
|
2321
|
+
expressionContext.a.b.set('b', { c: { d: 120 } });
|
|
2322
|
+
});
|
|
2323
|
+
|
|
2324
|
+
console.log(
|
|
2325
|
+
`Value of 'a.b['b'].c.d' after changing b['b'].c to '{ d: 220 }':`,
|
|
2326
|
+
);
|
|
2327
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2328
|
+
ignoreInitialValue: true,
|
|
2329
|
+
}).wait(() => {
|
|
2330
|
+
expressionContext.a.b.get('b').c = { d: 220 };
|
|
2331
|
+
});
|
|
2332
|
+
|
|
2333
|
+
console.log(`Value of 'a.b['b'].c.d' after changing b[1].c.d to '330':`);
|
|
2334
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2335
|
+
ignoreInitialValue: true,
|
|
2336
|
+
}).wait(() => {
|
|
2337
|
+
expressionContext.a.b.get('b').c.d = 330;
|
|
2338
|
+
});
|
|
2339
|
+
|
|
2340
|
+
console.log(`Final value of 'a.b['b'].c.d':`);
|
|
2341
|
+
printValue(expression.value);
|
|
2342
|
+
} finally {
|
|
2343
|
+
// Always dispose of expressions after use.
|
|
2344
|
+
expression.dispose();
|
|
2345
|
+
}
|
|
2346
|
+
})();
|
|
2347
|
+
```
|
|
2348
|
+
|
|
2349
|
+
- Member expression with method
|
|
2350
|
+
|
|
2351
|
+
```ts
|
|
2352
|
+
import {
|
|
2353
|
+
emptyFunction,
|
|
2354
|
+
InjectionContainer,
|
|
2355
|
+
printValue,
|
|
2356
|
+
WaitForEvent,
|
|
2357
|
+
} from '@rs-x/core';
|
|
2358
|
+
import {
|
|
2359
|
+
IExpressionFactory,
|
|
2360
|
+
RsXExpressionParserInjectionTokens,
|
|
2361
|
+
RsXExpressionParserModule,
|
|
2362
|
+
} from '@rs-x/expression-parser';
|
|
1805
2363
|
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
console.log(`Initial value of 'a.b.c':`)
|
|
1813
|
-
expression.changed.subscribe((change) => {
|
|
1814
|
-
printValue(change.value);
|
|
1815
|
-
});
|
|
1816
|
-
|
|
1817
|
-
console.log(`Value of 'a.b.c' after changing 'a' to '{b : {c: 20}}':`);
|
|
1818
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => { expressionContext.a = { b: { c: 20 } }; });
|
|
1819
|
-
|
|
1820
|
-
console.log(`Value of 'a.b.c' after changing 'b' to '{c: 30}':`);
|
|
1821
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => { expressionContext.a.b = { c: 30 }; });
|
|
1822
|
-
|
|
1823
|
-
console.log(`Value of 'a.b.c' after changing c to '40':`);
|
|
1824
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => { expressionContext.a.b.c = 40; });
|
|
1825
|
-
|
|
1826
|
-
console.log(`Final value of 'a.b.c':`)
|
|
1827
|
-
printValue(expression.value);
|
|
1828
|
-
} finally {
|
|
1829
|
-
// Always dispose of expressions after use.
|
|
1830
|
-
expression.dispose();
|
|
1831
|
-
}
|
|
1832
|
-
})();
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
```
|
|
1836
|
-
* Member expression with array
|
|
1837
|
-
```ts
|
|
1838
|
-
import { emptyFunction, InjectionContainer, printValue, WaitForEvent } from '@rs-x/core';
|
|
1839
|
-
import {
|
|
1840
|
-
IExpressionFactory,
|
|
1841
|
-
RsXExpressionParserInjectionTokens,
|
|
1842
|
-
RsXExpressionParserModule
|
|
1843
|
-
} from '@rs-x/expression-parser';
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
// Load the expression parser module into the injection container
|
|
1847
|
-
InjectionContainer.load(RsXExpressionParserModule);
|
|
1848
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(RsXExpressionParserInjectionTokens.IExpressionFactory);
|
|
1849
|
-
|
|
1850
|
-
export const run = (async () => {
|
|
1851
|
-
const expressionContext = {
|
|
1852
|
-
a: {
|
|
1853
|
-
b: [
|
|
1854
|
-
{
|
|
1855
|
-
c: {
|
|
1856
|
-
d: 10
|
|
1857
|
-
}
|
|
1858
|
-
},
|
|
1859
|
-
{
|
|
1860
|
-
c: {
|
|
1861
|
-
d: 11
|
|
1862
|
-
}
|
|
1863
|
-
},
|
|
1864
|
-
]
|
|
1865
|
-
},
|
|
1866
|
-
x: { y: 1 }
|
|
1867
|
-
};
|
|
2364
|
+
// Load the expression parser module into the injection container
|
|
2365
|
+
InjectionContainer.load(RsXExpressionParserModule);
|
|
2366
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2367
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2368
|
+
);
|
|
1868
2369
|
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
}
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
b: [
|
|
1884
|
-
{
|
|
1885
|
-
c: {
|
|
1886
|
-
d: 100
|
|
1887
|
-
}
|
|
1888
|
-
},
|
|
1889
|
-
{
|
|
1890
|
-
c: {
|
|
1891
|
-
d: 110
|
|
1892
|
-
}
|
|
1893
|
-
},
|
|
1894
|
-
]
|
|
1895
|
-
};
|
|
1896
|
-
});
|
|
1897
|
-
|
|
1898
|
-
console.log(`Value of 'a.b[1].c.d' after changing b[1] to '{ c: { d: 120}}':`);
|
|
1899
|
-
await new WaitForEvent(expression, 'changed', {ignoreInitialValue: true}).wait(() => {
|
|
1900
|
-
expressionContext.a.b[1] = {
|
|
1901
|
-
c: {
|
|
1902
|
-
d: 120
|
|
1903
|
-
}
|
|
1904
|
-
};
|
|
1905
|
-
});
|
|
1906
|
-
|
|
1907
|
-
console.log(`Value of 'a.b[1].c.d' after changing b[1].c to '{d: 220}':`);
|
|
1908
|
-
await new WaitForEvent(expression, 'changed', {ignoreInitialValue: true}).wait(() => { expressionContext.a.b[1].c = { d: 220 }; });
|
|
1909
|
-
|
|
1910
|
-
console.log(`Value of 'a.b[1].c.d' after changing b[1].c.d to '330':`);
|
|
1911
|
-
await new WaitForEvent(expression, 'changed', {ignoreInitialValue: true}).wait(() => { expressionContext.a.b[1].c.d = 330; });
|
|
1912
|
-
|
|
1913
|
-
console.log(`Final value of 'a.b[1].c.d':`)
|
|
1914
|
-
printValue(expression.value);
|
|
1915
|
-
} finally {
|
|
1916
|
-
// Always dispose of expressions after use.
|
|
1917
|
-
expression.dispose();
|
|
1918
|
-
}
|
|
1919
|
-
})();
|
|
1920
|
-
```
|
|
1921
|
-
* Member expression with map
|
|
1922
|
-
```ts
|
|
1923
|
-
import { emptyFunction, InjectionContainer, printValue, WaitForEvent } from '@rs-x/core';
|
|
1924
|
-
import {
|
|
1925
|
-
IExpressionFactory,
|
|
1926
|
-
RsXExpressionParserInjectionTokens,
|
|
1927
|
-
RsXExpressionParserModule
|
|
1928
|
-
} from '@rs-x/expression-parser';
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
// Load the expression parser module into the injection container
|
|
1932
|
-
InjectionContainer.load(RsXExpressionParserModule);
|
|
1933
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(RsXExpressionParserInjectionTokens.IExpressionFactory);
|
|
1934
|
-
|
|
1935
|
-
export const run = (async () => {
|
|
1936
|
-
const expressionContext = {
|
|
1937
|
-
a: {
|
|
1938
|
-
b: new Map([
|
|
1939
|
-
['a', { c: { d: 1 } }],
|
|
1940
|
-
['b', { c: { d: 2 } }]
|
|
1941
|
-
])
|
|
1942
|
-
}
|
|
1943
|
-
};
|
|
2370
|
+
export const run = (async () => {
|
|
2371
|
+
const expressionContext = {
|
|
2372
|
+
message: 'Hello',
|
|
2373
|
+
subject: 'Message',
|
|
2374
|
+
a: {
|
|
2375
|
+
b: {
|
|
2376
|
+
mail: (message: string, subject: string) => {
|
|
2377
|
+
return {
|
|
2378
|
+
messageWithSubject: `message: ${message}, subject: ${subject}`,
|
|
2379
|
+
};
|
|
2380
|
+
},
|
|
2381
|
+
},
|
|
2382
|
+
},
|
|
2383
|
+
};
|
|
1944
2384
|
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
1950
|
-
|
|
1951
|
-
console.log(`Initial value of 'a.b['b'].c.d':`);
|
|
1952
|
-
expression.changed.subscribe((change) => {
|
|
1953
|
-
printValue(change.value);
|
|
1954
|
-
});
|
|
1955
|
-
|
|
1956
|
-
console.log(`Value of 'a.b['b'].c.d' after changing 'a' to '{ b: new Map([['a', { c: { d: 11 } }], ['b', { c: { d: 21 } }]]) }':`);
|
|
1957
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
1958
|
-
expressionContext.a = {
|
|
1959
|
-
b: new Map([
|
|
1960
|
-
['a', { c: { d: 11 } }],
|
|
1961
|
-
['b', { c: { d: 21 } }]
|
|
1962
|
-
])
|
|
1963
|
-
}
|
|
1964
|
-
});
|
|
1965
|
-
|
|
1966
|
-
console.log(`Value of 'a.b['b'].c.d' after changing b['b'] to '{ c: { d: 120 } }':`);
|
|
1967
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
1968
|
-
expressionContext.a.b.set('b', { c: { d: 120 } });
|
|
1969
|
-
});
|
|
1970
|
-
|
|
1971
|
-
console.log(`Value of 'a.b['b'].c.d' after changing b['b'].c to '{ d: 220 }':`);
|
|
1972
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
1973
|
-
expressionContext.a.b.get('b').c = { d: 220 };
|
|
1974
|
-
});
|
|
1975
|
-
|
|
1976
|
-
console.log(`Value of 'a.b['b'].c.d' after changing b[1].c.d to '330':`);
|
|
1977
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
1978
|
-
expressionContext.a.b.get('b').c.d = 330;
|
|
1979
|
-
});
|
|
1980
|
-
|
|
1981
|
-
console.log(`Final value of 'a.b['b'].c.d':`)
|
|
1982
|
-
printValue(expression.value);
|
|
1983
|
-
} finally {
|
|
1984
|
-
// Always dispose of expressions after use.
|
|
1985
|
-
expression.dispose();
|
|
1986
|
-
}
|
|
1987
|
-
})();
|
|
1988
|
-
```
|
|
1989
|
-
* Member expression with method
|
|
1990
|
-
```ts
|
|
1991
|
-
import { emptyFunction, InjectionContainer, printValue, WaitForEvent } from '@rs-x/core';
|
|
1992
|
-
import {
|
|
1993
|
-
IExpressionFactory,
|
|
1994
|
-
RsXExpressionParserInjectionTokens,
|
|
1995
|
-
RsXExpressionParserModule
|
|
1996
|
-
} from '@rs-x/expression-parser';
|
|
1997
|
-
|
|
1998
|
-
// Load the expression parser module into the injection container
|
|
1999
|
-
InjectionContainer.load(RsXExpressionParserModule);
|
|
2000
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(RsXExpressionParserInjectionTokens.IExpressionFactory);
|
|
2001
|
-
|
|
2002
|
-
export const run = (async () => {
|
|
2003
|
-
const expressionContext = {
|
|
2004
|
-
message: 'Hello',
|
|
2005
|
-
subject: 'Message',
|
|
2006
|
-
a: {
|
|
2007
|
-
b: {
|
|
2008
|
-
mail: (message: string, subject: string) => {
|
|
2009
|
-
return {
|
|
2010
|
-
messageWithSubject: `message: ${message}, subject: ${subject}`
|
|
2011
|
-
};
|
|
2012
|
-
|
|
2013
|
-
}
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
};
|
|
2385
|
+
const expression = expressionFactory.create(
|
|
2386
|
+
expressionContext,
|
|
2387
|
+
'a.b.mail(message, subject).messageWithSubject',
|
|
2388
|
+
);
|
|
2017
2389
|
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
console.log(`Value of 'a.b.c.d' after emitting a new value '{ d: 300 }' for c':`);
|
|
2092
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
2093
|
-
nestedObservable.next({ d: 300 });
|
|
2094
|
-
});
|
|
2095
|
-
|
|
2096
|
-
console.log(`Value of 'a.b.c.d' after emitting a new value '{ c: new BehaviorSubject({ d: 400 }) }' for b':`);
|
|
2097
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => {
|
|
2098
|
-
rootObservable.next({
|
|
2099
|
-
c: new BehaviorSubject({ d: 400 })
|
|
2100
|
-
})
|
|
2101
|
-
});
|
|
2102
|
-
|
|
2103
|
-
console.log(`Final value of 'a.b.c.d':`)
|
|
2104
|
-
printValue(expression.value);
|
|
2105
|
-
} finally {
|
|
2106
|
-
// Always dispose of expressions after use.
|
|
2107
|
-
expression.dispose();
|
|
2108
|
-
}
|
|
2109
|
-
})();
|
|
2110
|
-
```
|
|
2111
|
-
* Member expression with promise
|
|
2112
|
-
```ts
|
|
2113
|
-
import { emptyFunction, InjectionContainer, printValue, WaitForEvent } from '@rs-x/core';
|
|
2114
|
-
import {
|
|
2115
|
-
IExpressionFactory,
|
|
2116
|
-
RsXExpressionParserInjectionTokens,
|
|
2117
|
-
RsXExpressionParserModule
|
|
2118
|
-
} from '@rs-x/expression-parser';
|
|
2119
|
-
|
|
2120
|
-
// Load the expression parser module into the injection container
|
|
2121
|
-
InjectionContainer.load(RsXExpressionParserModule);
|
|
2122
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(RsXExpressionParserInjectionTokens.IExpressionFactory);
|
|
2123
|
-
|
|
2124
|
-
export const run = (async () => {
|
|
2125
|
-
const expressionContext = {
|
|
2126
|
-
a: {
|
|
2127
|
-
b: Promise.resolve({
|
|
2128
|
-
c: Promise.resolve({
|
|
2129
|
-
d: 20
|
|
2130
|
-
})
|
|
2131
|
-
})
|
|
2132
|
-
}
|
|
2133
|
-
};
|
|
2390
|
+
try {
|
|
2391
|
+
// Wait until the expression has been resolved (has a value)
|
|
2392
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2393
|
+
|
|
2394
|
+
console.log(
|
|
2395
|
+
`Initial value of 'a.b.mail(message, subject).messageWithSubject':`,
|
|
2396
|
+
);
|
|
2397
|
+
expression.changed.subscribe((change) => {
|
|
2398
|
+
printValue(change.value);
|
|
2399
|
+
});
|
|
2400
|
+
|
|
2401
|
+
console.log(
|
|
2402
|
+
`Value of 'a.b.mail(message, subject).messageWithSubject' after changing 'message' to 'hi'`,
|
|
2403
|
+
);
|
|
2404
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2405
|
+
ignoreInitialValue: true,
|
|
2406
|
+
}).wait(() => {
|
|
2407
|
+
expressionContext.message = 'hi';
|
|
2408
|
+
});
|
|
2409
|
+
|
|
2410
|
+
console.log(
|
|
2411
|
+
`Value of 'a.b.mail(message, subject).messageWithSubject' after changing 'subject' to 'urgent message'`,
|
|
2412
|
+
);
|
|
2413
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2414
|
+
ignoreInitialValue: true,
|
|
2415
|
+
}).wait(() => {
|
|
2416
|
+
expressionContext.subject = 'urgent message';
|
|
2417
|
+
});
|
|
2418
|
+
|
|
2419
|
+
console.log(
|
|
2420
|
+
`Final value of 'a.b.mail(message, subject).messageWithSubject':`,
|
|
2421
|
+
);
|
|
2422
|
+
printValue(expression.value);
|
|
2423
|
+
} finally {
|
|
2424
|
+
// Always dispose of expressions after use.
|
|
2425
|
+
expression.dispose();
|
|
2426
|
+
}
|
|
2427
|
+
})();
|
|
2428
|
+
```
|
|
2429
|
+
|
|
2430
|
+
- Member expression with observable
|
|
2431
|
+
|
|
2432
|
+
```ts
|
|
2433
|
+
import {
|
|
2434
|
+
emptyFunction,
|
|
2435
|
+
InjectionContainer,
|
|
2436
|
+
printValue,
|
|
2437
|
+
WaitForEvent,
|
|
2438
|
+
} from '@rs-x/core';
|
|
2439
|
+
import {
|
|
2440
|
+
IExpressionFactory,
|
|
2441
|
+
RsXExpressionParserInjectionTokens,
|
|
2442
|
+
RsXExpressionParserModule,
|
|
2443
|
+
} from '@rs-x/expression-parser';
|
|
2444
|
+
import { BehaviorSubject } from 'rxjs';
|
|
2445
|
+
|
|
2446
|
+
// Load the expression parser module into the injection container
|
|
2447
|
+
InjectionContainer.load(RsXExpressionParserModule);
|
|
2448
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2449
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2450
|
+
);
|
|
2451
|
+
|
|
2452
|
+
export const run = (async () => {
|
|
2453
|
+
const nestedObservable = new BehaviorSubject({ d: 200 });
|
|
2454
|
+
const rootObservable = new BehaviorSubject({ c: nestedObservable });
|
|
2455
|
+
const expressionContext = {
|
|
2456
|
+
a: {
|
|
2457
|
+
b: new BehaviorSubject({
|
|
2458
|
+
c: new BehaviorSubject({ d: 20 }),
|
|
2459
|
+
}),
|
|
2460
|
+
},
|
|
2461
|
+
};
|
|
2462
|
+
const expression = expressionFactory.create(expressionContext, `a.b.c.d`);
|
|
2134
2463
|
|
|
2135
|
-
|
|
2464
|
+
try {
|
|
2465
|
+
// Wait until the expression has been resolved (has a value)
|
|
2466
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2467
|
+
|
|
2468
|
+
console.log(`Initial value of 'a.b.c.d':`);
|
|
2469
|
+
expression.changed.subscribe((change) => {
|
|
2470
|
+
printValue(change.value);
|
|
2471
|
+
});
|
|
2472
|
+
|
|
2473
|
+
console.log(
|
|
2474
|
+
`Value of 'a.b.c.d' after changing 'a' to '{ b: BehaviorSubject({ c: BehaviorSubject({ d: 200 }) }) }':`,
|
|
2475
|
+
);
|
|
2476
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2477
|
+
ignoreInitialValue: true,
|
|
2478
|
+
}).wait(() => {
|
|
2479
|
+
expressionContext.a = { b: rootObservable };
|
|
2480
|
+
});
|
|
2481
|
+
|
|
2482
|
+
console.log(
|
|
2483
|
+
`Value of 'a.b.c.d' after emitting a new value '{ d: 300 }' for c':`,
|
|
2484
|
+
);
|
|
2485
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2486
|
+
ignoreInitialValue: true,
|
|
2487
|
+
}).wait(() => {
|
|
2488
|
+
nestedObservable.next({ d: 300 });
|
|
2489
|
+
});
|
|
2490
|
+
|
|
2491
|
+
console.log(
|
|
2492
|
+
`Value of 'a.b.c.d' after emitting a new value '{ c: new BehaviorSubject({ d: 400 }) }' for b':`,
|
|
2493
|
+
);
|
|
2494
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2495
|
+
ignoreInitialValue: true,
|
|
2496
|
+
}).wait(() => {
|
|
2497
|
+
rootObservable.next({
|
|
2498
|
+
c: new BehaviorSubject({ d: 400 }),
|
|
2499
|
+
});
|
|
2500
|
+
});
|
|
2136
2501
|
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2502
|
+
console.log(`Final value of 'a.b.c.d':`);
|
|
2503
|
+
printValue(expression.value);
|
|
2504
|
+
} finally {
|
|
2505
|
+
// Always dispose of expressions after use.
|
|
2506
|
+
expression.dispose();
|
|
2507
|
+
}
|
|
2508
|
+
})();
|
|
2509
|
+
```
|
|
2510
|
+
|
|
2511
|
+
- Member expression with promise
|
|
2512
|
+
|
|
2513
|
+
```ts
|
|
2514
|
+
import {
|
|
2515
|
+
emptyFunction,
|
|
2516
|
+
InjectionContainer,
|
|
2517
|
+
printValue,
|
|
2518
|
+
WaitForEvent,
|
|
2519
|
+
} from '@rs-x/core';
|
|
2520
|
+
import {
|
|
2521
|
+
IExpressionFactory,
|
|
2522
|
+
RsXExpressionParserInjectionTokens,
|
|
2523
|
+
RsXExpressionParserModule,
|
|
2524
|
+
} from '@rs-x/expression-parser';
|
|
2140
2525
|
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2526
|
+
// Load the expression parser module into the injection container
|
|
2527
|
+
InjectionContainer.load(RsXExpressionParserModule);
|
|
2528
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2529
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2530
|
+
);
|
|
2145
2531
|
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2532
|
+
export const run = (async () => {
|
|
2533
|
+
const expressionContext = {
|
|
2534
|
+
a: {
|
|
2535
|
+
b: Promise.resolve({
|
|
2536
|
+
c: Promise.resolve({
|
|
2537
|
+
d: 20,
|
|
2538
|
+
}),
|
|
2539
|
+
}),
|
|
2540
|
+
},
|
|
2541
|
+
};
|
|
2150
2542
|
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2543
|
+
const expression = expressionFactory.create(expressionContext, `a.b.c.d`);
|
|
2544
|
+
|
|
2545
|
+
try {
|
|
2546
|
+
// Wait until the expression has been resolved (has a value)
|
|
2547
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2548
|
+
|
|
2549
|
+
console.log(`Initial value of 'a.b.c.d':`);
|
|
2550
|
+
expression.changed.subscribe((change) => {
|
|
2551
|
+
printValue(change.value);
|
|
2552
|
+
});
|
|
2553
|
+
|
|
2554
|
+
console.log(
|
|
2555
|
+
`Value of 'a.b.c.d' after changing 'a' to '{ b: Promise.resolve({ c: Promise.resolve({ d: 200 }) }) }':`,
|
|
2556
|
+
);
|
|
2557
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2558
|
+
ignoreInitialValue: true,
|
|
2559
|
+
}).wait(() => {
|
|
2560
|
+
expressionContext.a = {
|
|
2561
|
+
b: Promise.resolve({ c: Promise.resolve({ d: 200 }) }),
|
|
2562
|
+
};
|
|
2563
|
+
});
|
|
2564
|
+
|
|
2565
|
+
console.log(`Final value of 'a.b.c.d':`);
|
|
2566
|
+
printValue(expression.value);
|
|
2567
|
+
} finally {
|
|
2568
|
+
// Always dispose of expressions after use.
|
|
2569
|
+
expression.dispose();
|
|
2570
|
+
}
|
|
2571
|
+
})();
|
|
2572
|
+
```
|
|
2159
2573
|
|
|
2160
2574
|
### Multiplication expression
|
|
2161
2575
|
|
|
2162
2576
|
```ts
|
|
2163
2577
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2164
2578
|
import {
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2579
|
+
IExpressionFactory,
|
|
2580
|
+
RsXExpressionParserInjectionTokens,
|
|
2581
|
+
RsXExpressionParserModule,
|
|
2168
2582
|
} from '@rs-x/expression-parser';
|
|
2169
2583
|
|
|
2170
2584
|
// Load the expression parser module into the injection container
|
|
2171
2585
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2172
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2586
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2587
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2588
|
+
);
|
|
2173
2589
|
|
|
2174
2590
|
export const run = (async () => {
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2591
|
+
const expressionContext = {
|
|
2592
|
+
a: 1,
|
|
2593
|
+
b: 3,
|
|
2594
|
+
};
|
|
2179
2595
|
|
|
2180
|
-
|
|
2596
|
+
const expression = expressionFactory.create(expressionContext, 'a * b');
|
|
2181
2597
|
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2598
|
+
try {
|
|
2599
|
+
// Wait until the expression has been resolved (has a value)
|
|
2600
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2185
2601
|
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2602
|
+
console.log(`Initial value of 'a * b':`);
|
|
2603
|
+
expression.changed.subscribe((change) => {
|
|
2604
|
+
console.log(change.value);
|
|
2605
|
+
});
|
|
2190
2606
|
|
|
2191
|
-
|
|
2192
|
-
|
|
2607
|
+
console.log(`Value of 'a * b' after changing 'a' to '6':`);
|
|
2608
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2609
|
+
ignoreInitialValue: true,
|
|
2610
|
+
}).wait(() => {
|
|
2611
|
+
expressionContext.a = 6;
|
|
2612
|
+
});
|
|
2193
2613
|
|
|
2194
|
-
|
|
2195
|
-
|
|
2614
|
+
console.log(`Value of 'a * b' after changing 'b' to '4':`);
|
|
2615
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2616
|
+
ignoreInitialValue: true,
|
|
2617
|
+
}).wait(() => {
|
|
2618
|
+
expressionContext.b = 4;
|
|
2619
|
+
});
|
|
2196
2620
|
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2621
|
+
console.log(`Final value of 'a * b':`);
|
|
2622
|
+
console.log(expression.value);
|
|
2623
|
+
} finally {
|
|
2624
|
+
// Always dispose of expressions after use.
|
|
2625
|
+
expression.dispose();
|
|
2626
|
+
}
|
|
2203
2627
|
})();
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
2628
|
```
|
|
2207
2629
|
|
|
2208
2630
|
### New expression
|
|
2209
2631
|
|
|
2210
2632
|
```ts
|
|
2211
|
-
import { emptyFunction, InjectionContainer, printValue, WaitForEvent } from '@rs-x/core';
|
|
2212
2633
|
import {
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2634
|
+
emptyFunction,
|
|
2635
|
+
InjectionContainer,
|
|
2636
|
+
printValue,
|
|
2637
|
+
WaitForEvent,
|
|
2638
|
+
} from '@rs-x/core';
|
|
2639
|
+
import {
|
|
2640
|
+
IExpressionFactory,
|
|
2641
|
+
RsXExpressionParserInjectionTokens,
|
|
2642
|
+
RsXExpressionParserModule,
|
|
2216
2643
|
} from '@rs-x/expression-parser';
|
|
2217
2644
|
|
|
2218
2645
|
// Load the expression parser module into the injection container
|
|
2219
2646
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2220
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2647
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2648
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2649
|
+
);
|
|
2221
2650
|
|
|
2222
2651
|
export const run = (async () => {
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2652
|
+
class Value {
|
|
2653
|
+
constructor(public readonly value: number) {}
|
|
2654
|
+
}
|
|
2226
2655
|
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
}
|
|
2656
|
+
class Add10 {
|
|
2657
|
+
constructor(public readonly value: number) {
|
|
2658
|
+
this.value += 10;
|
|
2231
2659
|
}
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
const expressionContext = {
|
|
2663
|
+
type: Value,
|
|
2664
|
+
value: 10,
|
|
2665
|
+
};
|
|
2666
|
+
|
|
2667
|
+
const expression = expressionFactory.create(
|
|
2668
|
+
expressionContext,
|
|
2669
|
+
'new type(value)',
|
|
2670
|
+
);
|
|
2671
|
+
|
|
2672
|
+
function print(instance: unknown): void {
|
|
2673
|
+
console.log(instance.constructor.name);
|
|
2674
|
+
printValue(instance);
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
try {
|
|
2678
|
+
// Wait until the expression has been resolved (has a value)
|
|
2679
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2680
|
+
|
|
2681
|
+
console.log(`Initial value of 'new type(value)':`);
|
|
2682
|
+
expression.changed.subscribe((change) => {
|
|
2683
|
+
print(change.value);
|
|
2684
|
+
});
|
|
2232
2685
|
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
}
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
function print(instance: unknown): void {
|
|
2241
|
-
console.log(instance.constructor.name);
|
|
2242
|
-
printValue(instance);
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
try {
|
|
2246
|
-
// Wait until the expression has been resolved (has a value)
|
|
2247
|
-
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2248
|
-
|
|
2249
|
-
console.log(`Initial value of 'new type(value)':`);
|
|
2250
|
-
expression.changed.subscribe((change) => {
|
|
2251
|
-
print(change.value)
|
|
2252
|
-
});
|
|
2253
|
-
|
|
2254
|
-
console.log(`Value of 'new type(value)' after changing 'value' to '20':`);
|
|
2255
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => { expressionContext.value = 20; })
|
|
2256
|
-
|
|
2257
|
-
console.log(`Value of 'new type(value)' after changing 'type' to 'Add10':`)
|
|
2258
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => { expressionContext.type = Add10; })
|
|
2686
|
+
console.log(`Value of 'new type(value)' after changing 'value' to '20':`);
|
|
2687
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2688
|
+
ignoreInitialValue: true,
|
|
2689
|
+
}).wait(() => {
|
|
2690
|
+
expressionContext.value = 20;
|
|
2691
|
+
});
|
|
2259
2692
|
|
|
2260
|
-
|
|
2261
|
-
|
|
2693
|
+
console.log(`Value of 'new type(value)' after changing 'type' to 'Add10':`);
|
|
2694
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2695
|
+
ignoreInitialValue: true,
|
|
2696
|
+
}).wait(() => {
|
|
2697
|
+
expressionContext.type = Add10;
|
|
2698
|
+
});
|
|
2262
2699
|
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2700
|
+
console.log(`Final value of 'new type(value)':`);
|
|
2701
|
+
print(expression.value);
|
|
2702
|
+
} finally {
|
|
2703
|
+
// Always dispose of expressions after use.
|
|
2704
|
+
expression.dispose();
|
|
2705
|
+
}
|
|
2267
2706
|
})();
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
2707
|
```
|
|
2271
2708
|
|
|
2272
2709
|
### Nullish coalescing expression
|
|
@@ -2274,100 +2711,126 @@ export const run = (async () => {
|
|
|
2274
2711
|
```ts
|
|
2275
2712
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2276
2713
|
import {
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2714
|
+
IExpressionFactory,
|
|
2715
|
+
RsXExpressionParserInjectionTokens,
|
|
2716
|
+
RsXExpressionParserModule,
|
|
2280
2717
|
} from '@rs-x/expression-parser';
|
|
2281
2718
|
|
|
2282
2719
|
// Load the expression parser module into the injection container
|
|
2283
2720
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2284
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2721
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2722
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2723
|
+
);
|
|
2285
2724
|
|
|
2286
2725
|
export const run = (async () => {
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2726
|
+
const expressionContext = {
|
|
2727
|
+
a: null,
|
|
2728
|
+
b: 10,
|
|
2729
|
+
};
|
|
2291
2730
|
|
|
2292
|
-
|
|
2731
|
+
const expression = expressionFactory.create(expressionContext, 'a ?? b');
|
|
2293
2732
|
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2733
|
+
try {
|
|
2734
|
+
// Wait until the expression has been resolved (has a value)
|
|
2735
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2297
2736
|
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
console.log(`Value of 'a ?? b' after changing 'b' to '6':`);
|
|
2304
|
-
await new WaitForEvent(expression, 'changed', { ignoreInitialValue: true }).wait(() => { expressionContext.b = 6; })
|
|
2737
|
+
console.log(`Initial value of 'a ?? b':`);
|
|
2738
|
+
expression.changed.subscribe((change) => {
|
|
2739
|
+
console.log(change.value);
|
|
2740
|
+
});
|
|
2305
2741
|
|
|
2306
|
-
|
|
2307
|
-
|
|
2742
|
+
console.log(`Value of 'a ?? b' after changing 'b' to '6':`);
|
|
2743
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2744
|
+
ignoreInitialValue: true,
|
|
2745
|
+
}).wait(() => {
|
|
2746
|
+
expressionContext.b = 6;
|
|
2747
|
+
});
|
|
2308
2748
|
|
|
2309
|
-
|
|
2310
|
-
|
|
2749
|
+
console.log(`Value of 'a ?? b' after changing 'a' to '10':`);
|
|
2750
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2751
|
+
ignoreInitialValue: true,
|
|
2752
|
+
}).wait(() => {
|
|
2753
|
+
expressionContext.a = 10;
|
|
2754
|
+
});
|
|
2311
2755
|
|
|
2756
|
+
console.log(`Value of 'a ?? b' after changing 'a' to 'null':`);
|
|
2757
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2758
|
+
ignoreInitialValue: true,
|
|
2759
|
+
}).wait(() => {
|
|
2760
|
+
expressionContext.a = null;
|
|
2761
|
+
});
|
|
2312
2762
|
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2763
|
+
console.log(`Final value of 'a ?? b'':`);
|
|
2764
|
+
console.log(expression.value);
|
|
2765
|
+
} finally {
|
|
2766
|
+
// Always dispose of expressions after use.
|
|
2767
|
+
expression.dispose();
|
|
2768
|
+
}
|
|
2319
2769
|
})();
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
2770
|
```
|
|
2323
2771
|
|
|
2324
2772
|
### Object expression
|
|
2325
2773
|
|
|
2326
2774
|
```ts
|
|
2327
|
-
import { emptyFunction, InjectionContainer, printValue, WaitForEvent } from '@rs-x/core';
|
|
2328
2775
|
import {
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2776
|
+
emptyFunction,
|
|
2777
|
+
InjectionContainer,
|
|
2778
|
+
printValue,
|
|
2779
|
+
WaitForEvent,
|
|
2780
|
+
} from '@rs-x/core';
|
|
2781
|
+
import {
|
|
2782
|
+
IExpressionFactory,
|
|
2783
|
+
RsXExpressionParserInjectionTokens,
|
|
2784
|
+
RsXExpressionParserModule,
|
|
2332
2785
|
} from '@rs-x/expression-parser';
|
|
2333
2786
|
|
|
2334
2787
|
// Load the expression parser module into the injection container
|
|
2335
2788
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2336
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2789
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2790
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2791
|
+
);
|
|
2337
2792
|
|
|
2338
2793
|
export const run = (async () => {
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2794
|
+
const expressionContext = {
|
|
2795
|
+
x: 10,
|
|
2796
|
+
y: 20,
|
|
2797
|
+
};
|
|
2798
|
+
|
|
2799
|
+
const expression = expressionFactory.create(
|
|
2800
|
+
expressionContext,
|
|
2801
|
+
'({ a: x, b: y })',
|
|
2802
|
+
);
|
|
2803
|
+
|
|
2804
|
+
try {
|
|
2805
|
+
// Wait until the expression has been resolved (has a value)
|
|
2806
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2807
|
+
|
|
2808
|
+
console.log(`Initial value of '({ a: x, b: y })':`);
|
|
2809
|
+
expression.changed.subscribe((change) => {
|
|
2810
|
+
printValue(change.value);
|
|
2811
|
+
});
|
|
2357
2812
|
|
|
2358
|
-
|
|
2359
|
-
|
|
2813
|
+
console.log(`Value of '({ a: x, b: y })' after changing 'x' to '100':`);
|
|
2814
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2815
|
+
ignoreInitialValue: true,
|
|
2816
|
+
}).wait(() => {
|
|
2817
|
+
expressionContext.x = 100;
|
|
2818
|
+
});
|
|
2360
2819
|
|
|
2361
|
-
|
|
2362
|
-
|
|
2820
|
+
console.log(`Value of '({ a: x, b: y })' after changing 'y' to '200':`);
|
|
2821
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2822
|
+
ignoreInitialValue: true,
|
|
2823
|
+
}).wait(() => {
|
|
2824
|
+
expressionContext.y = 200;
|
|
2825
|
+
});
|
|
2363
2826
|
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2827
|
+
console.log(`Final value of '({ a: x, b: y })':`);
|
|
2828
|
+
printValue(expression.value);
|
|
2829
|
+
} finally {
|
|
2830
|
+
// Always dispose of expressions after use.
|
|
2831
|
+
expression.dispose();
|
|
2832
|
+
}
|
|
2368
2833
|
})();
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
2834
|
```
|
|
2372
2835
|
|
|
2373
2836
|
### Remainder expression
|
|
@@ -2375,47 +2838,55 @@ export const run = (async () => {
|
|
|
2375
2838
|
```ts
|
|
2376
2839
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2377
2840
|
import {
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2841
|
+
IExpressionFactory,
|
|
2842
|
+
RsXExpressionParserInjectionTokens,
|
|
2843
|
+
RsXExpressionParserModule,
|
|
2381
2844
|
} from '@rs-x/expression-parser';
|
|
2382
2845
|
|
|
2383
2846
|
// Load the expression parser module into the injection container
|
|
2384
2847
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2385
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2848
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2849
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2850
|
+
);
|
|
2386
2851
|
|
|
2387
2852
|
export const run = (async () => {
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2853
|
+
const expressionContext = {
|
|
2854
|
+
a: 5,
|
|
2855
|
+
b: 2,
|
|
2856
|
+
};
|
|
2392
2857
|
|
|
2393
|
-
|
|
2858
|
+
const expression = expressionFactory.create(expressionContext, 'a % b');
|
|
2394
2859
|
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2860
|
+
try {
|
|
2861
|
+
// Wait until the expression has been resolved (has a value)
|
|
2862
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2398
2863
|
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2864
|
+
console.log(`Initial value of a % b':`);
|
|
2865
|
+
expression.changed.subscribe((change) => {
|
|
2866
|
+
console.log(change.value);
|
|
2867
|
+
});
|
|
2403
2868
|
|
|
2404
|
-
|
|
2405
|
-
|
|
2869
|
+
console.log(`Value of 'a % b' after changing 'a' to '6':`);
|
|
2870
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2871
|
+
ignoreInitialValue: true,
|
|
2872
|
+
}).wait(() => {
|
|
2873
|
+
expressionContext.a = 6;
|
|
2874
|
+
});
|
|
2406
2875
|
|
|
2407
|
-
|
|
2408
|
-
|
|
2876
|
+
console.log(`Value of 'a % b after changing 'b' to '4':`);
|
|
2877
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2878
|
+
ignoreInitialValue: true,
|
|
2879
|
+
}).wait(() => {
|
|
2880
|
+
expressionContext.b = 4;
|
|
2881
|
+
});
|
|
2409
2882
|
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2883
|
+
console.log(`Final value of 'a % b':`);
|
|
2884
|
+
console.log(expression.value);
|
|
2885
|
+
} finally {
|
|
2886
|
+
// Always dispose of expressions after use.
|
|
2887
|
+
expression.dispose();
|
|
2888
|
+
}
|
|
2416
2889
|
})();
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
2890
|
```
|
|
2420
2891
|
|
|
2421
2892
|
### Sequence expression
|
|
@@ -2423,52 +2894,63 @@ export const run = (async () => {
|
|
|
2423
2894
|
```ts
|
|
2424
2895
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2425
2896
|
import {
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2897
|
+
IExpressionFactory,
|
|
2898
|
+
RsXExpressionParserInjectionTokens,
|
|
2899
|
+
RsXExpressionParserModule,
|
|
2429
2900
|
} from '@rs-x/expression-parser';
|
|
2430
2901
|
|
|
2431
2902
|
// Load the expression parser module into the injection container
|
|
2432
2903
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2433
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2904
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2905
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2906
|
+
);
|
|
2434
2907
|
|
|
2435
2908
|
export const run = (async () => {
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2909
|
+
const expressionContext = {
|
|
2910
|
+
b: 2,
|
|
2911
|
+
value: 100,
|
|
2912
|
+
setB(v: number) {
|
|
2913
|
+
this.b = v;
|
|
2914
|
+
},
|
|
2915
|
+
};
|
|
2916
|
+
|
|
2917
|
+
const expression = expressionFactory.create(
|
|
2918
|
+
expressionContext,
|
|
2919
|
+
'(setB(value), b)',
|
|
2920
|
+
);
|
|
2921
|
+
|
|
2922
|
+
try {
|
|
2923
|
+
// Wait until the expression has been resolved (has a value)
|
|
2924
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2925
|
+
|
|
2926
|
+
console.log(`Initial value of (setB(value), b)':`);
|
|
2927
|
+
expression.changed.subscribe((change) => {
|
|
2928
|
+
console.log(change.value);
|
|
2929
|
+
});
|
|
2458
2930
|
|
|
2459
|
-
|
|
2460
|
-
|
|
2931
|
+
console.log(
|
|
2932
|
+
`Value of '(setB(value)', b)' after changing 'value' to '200':`,
|
|
2933
|
+
);
|
|
2934
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2935
|
+
ignoreInitialValue: true,
|
|
2936
|
+
}).wait(() => {
|
|
2937
|
+
expressionContext.value = 200;
|
|
2938
|
+
});
|
|
2461
2939
|
|
|
2940
|
+
console.log(`Value of '(setB(value)', b)' after changing 'b' to '300':`);
|
|
2941
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2942
|
+
ignoreInitialValue: true,
|
|
2943
|
+
}).wait(() => {
|
|
2944
|
+
expressionContext.b = 300;
|
|
2945
|
+
});
|
|
2462
2946
|
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2947
|
+
console.log(`Final value of '(setB(value), b)':`);
|
|
2948
|
+
console.log(expression.value);
|
|
2949
|
+
} finally {
|
|
2950
|
+
// Always dispose of expressions after use.
|
|
2951
|
+
expression.dispose();
|
|
2952
|
+
}
|
|
2469
2953
|
})();
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
2954
|
```
|
|
2473
2955
|
|
|
2474
2956
|
### Strict equality expression
|
|
@@ -2476,47 +2958,55 @@ export const run = (async () => {
|
|
|
2476
2958
|
```ts
|
|
2477
2959
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2478
2960
|
import {
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2961
|
+
IExpressionFactory,
|
|
2962
|
+
RsXExpressionParserInjectionTokens,
|
|
2963
|
+
RsXExpressionParserModule,
|
|
2482
2964
|
} from '@rs-x/expression-parser';
|
|
2483
2965
|
|
|
2484
2966
|
// Load the expression parser module into the injection container
|
|
2485
2967
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2486
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2968
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
2969
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
2970
|
+
);
|
|
2487
2971
|
|
|
2488
2972
|
export const run = (async () => {
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2973
|
+
const expressionContext = {
|
|
2974
|
+
a: 3,
|
|
2975
|
+
b: 2 as string | number,
|
|
2976
|
+
};
|
|
2493
2977
|
|
|
2494
|
-
|
|
2978
|
+
const expression = expressionFactory.create(expressionContext, 'a === b');
|
|
2495
2979
|
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2980
|
+
try {
|
|
2981
|
+
// Wait until the expression has been resolved (has a value)
|
|
2982
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2499
2983
|
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2984
|
+
console.log(`Initial value of 'a === b':`);
|
|
2985
|
+
expression.changed.subscribe((change) => {
|
|
2986
|
+
console.log(change.value);
|
|
2987
|
+
});
|
|
2504
2988
|
|
|
2505
|
-
|
|
2506
|
-
|
|
2989
|
+
console.log(`Value of 'a === b' after changing 'a' to '2':`);
|
|
2990
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2991
|
+
ignoreInitialValue: true,
|
|
2992
|
+
}).wait(() => {
|
|
2993
|
+
expressionContext.a = 2;
|
|
2994
|
+
});
|
|
2507
2995
|
|
|
2508
|
-
|
|
2509
|
-
|
|
2996
|
+
console.log(`Value of 'a === b' after changing 'b' to '"2"':`);
|
|
2997
|
+
await new WaitForEvent(expression, 'changed', {
|
|
2998
|
+
ignoreInitialValue: true,
|
|
2999
|
+
}).wait(() => {
|
|
3000
|
+
expressionContext.b = '2';
|
|
3001
|
+
});
|
|
2510
3002
|
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
3003
|
+
console.log(`Final value of 'a === b':`);
|
|
3004
|
+
console.log(expression.value);
|
|
3005
|
+
} finally {
|
|
3006
|
+
// Always dispose of expressions after use.
|
|
3007
|
+
expression.dispose();
|
|
3008
|
+
}
|
|
2517
3009
|
})();
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
3010
|
```
|
|
2521
3011
|
|
|
2522
3012
|
### Strict inequality expression
|
|
@@ -2524,47 +3014,55 @@ export const run = (async () => {
|
|
|
2524
3014
|
```ts
|
|
2525
3015
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2526
3016
|
import {
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
3017
|
+
IExpressionFactory,
|
|
3018
|
+
RsXExpressionParserInjectionTokens,
|
|
3019
|
+
RsXExpressionParserModule,
|
|
2530
3020
|
} from '@rs-x/expression-parser';
|
|
2531
3021
|
|
|
2532
3022
|
// Load the expression parser module into the injection container
|
|
2533
3023
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2534
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3024
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3025
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
3026
|
+
);
|
|
2535
3027
|
|
|
2536
3028
|
export const run = (async () => {
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
3029
|
+
const expressionContext = {
|
|
3030
|
+
a: 2 as string | number,
|
|
3031
|
+
b: 2 as string | number,
|
|
3032
|
+
};
|
|
2541
3033
|
|
|
2542
|
-
|
|
3034
|
+
const expression = expressionFactory.create(expressionContext, 'a !== b');
|
|
2543
3035
|
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
3036
|
+
try {
|
|
3037
|
+
// Wait until the expression has been resolved (has a value)
|
|
3038
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2547
3039
|
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
3040
|
+
console.log(`Initial value of 'a !== b':`);
|
|
3041
|
+
expression.changed.subscribe((change) => {
|
|
3042
|
+
console.log(change.value);
|
|
3043
|
+
});
|
|
2552
3044
|
|
|
2553
|
-
|
|
2554
|
-
|
|
3045
|
+
console.log(`Value of 'a !== b' after changing 'a' to '"2"':`);
|
|
3046
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3047
|
+
ignoreInitialValue: true,
|
|
3048
|
+
}).wait(() => {
|
|
3049
|
+
expressionContext.a = '2';
|
|
3050
|
+
});
|
|
2555
3051
|
|
|
2556
|
-
|
|
2557
|
-
|
|
3052
|
+
console.log(`Value of 'a !== b' after changing 'b' to '"2"':`);
|
|
3053
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3054
|
+
ignoreInitialValue: true,
|
|
3055
|
+
}).wait(() => {
|
|
3056
|
+
expressionContext.b = '2';
|
|
3057
|
+
});
|
|
2558
3058
|
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
3059
|
+
console.log(`Final value of 'a !== b':`);
|
|
3060
|
+
console.log(expression.value);
|
|
3061
|
+
} finally {
|
|
3062
|
+
// Always dispose of expressions after use.
|
|
3063
|
+
expression.dispose();
|
|
3064
|
+
}
|
|
2565
3065
|
})();
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
3066
|
```
|
|
2569
3067
|
|
|
2570
3068
|
### Substraction expression
|
|
@@ -2572,47 +3070,55 @@ export const run = (async () => {
|
|
|
2572
3070
|
```ts
|
|
2573
3071
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2574
3072
|
import {
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
3073
|
+
IExpressionFactory,
|
|
3074
|
+
RsXExpressionParserInjectionTokens,
|
|
3075
|
+
RsXExpressionParserModule,
|
|
2578
3076
|
} from '@rs-x/expression-parser';
|
|
2579
3077
|
|
|
2580
3078
|
// Load the expression parser module into the injection container
|
|
2581
3079
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2582
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3080
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3081
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
3082
|
+
);
|
|
2583
3083
|
|
|
2584
3084
|
export const run = (async () => {
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
3085
|
+
const expressionContext = {
|
|
3086
|
+
a: 1,
|
|
3087
|
+
b: 3,
|
|
3088
|
+
};
|
|
2589
3089
|
|
|
2590
|
-
|
|
3090
|
+
const expression = expressionFactory.create(expressionContext, 'a - b');
|
|
2591
3091
|
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
3092
|
+
try {
|
|
3093
|
+
// Wait until the expression has been resolved (has a value)
|
|
3094
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2595
3095
|
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
3096
|
+
console.log(`Initial value of 'a - b':`);
|
|
3097
|
+
expression.changed.subscribe((change) => {
|
|
3098
|
+
console.log(change.value);
|
|
3099
|
+
});
|
|
2600
3100
|
|
|
2601
|
-
|
|
2602
|
-
|
|
3101
|
+
console.log(`Value of 'a - b' after changing 'a' to '6':`);
|
|
3102
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3103
|
+
ignoreInitialValue: true,
|
|
3104
|
+
}).wait(() => {
|
|
3105
|
+
expressionContext.a = 6;
|
|
3106
|
+
});
|
|
2603
3107
|
|
|
2604
|
-
|
|
2605
|
-
|
|
3108
|
+
console.log(`Value of 'a - b' after changing 'b' to '4':`);
|
|
3109
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3110
|
+
ignoreInitialValue: true,
|
|
3111
|
+
}).wait(() => {
|
|
3112
|
+
expressionContext.b = 4;
|
|
3113
|
+
});
|
|
2606
3114
|
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
3115
|
+
console.log(`Final value of 'a - b':`);
|
|
3116
|
+
console.log(expression.value);
|
|
3117
|
+
} finally {
|
|
3118
|
+
// Always dispose of expressions after use.
|
|
3119
|
+
expression.dispose();
|
|
3120
|
+
}
|
|
2613
3121
|
})();
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
3122
|
```
|
|
2617
3123
|
|
|
2618
3124
|
### Template string expression
|
|
@@ -2620,43 +3126,52 @@ export const run = (async () => {
|
|
|
2620
3126
|
```ts
|
|
2621
3127
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2622
3128
|
import {
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
3129
|
+
IExpressionFactory,
|
|
3130
|
+
RsXExpressionParserInjectionTokens,
|
|
3131
|
+
RsXExpressionParserModule,
|
|
2626
3132
|
} from '@rs-x/expression-parser';
|
|
2627
3133
|
|
|
2628
3134
|
// Load the expression parser module into the injection container
|
|
2629
3135
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2630
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3136
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3137
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
3138
|
+
);
|
|
2631
3139
|
|
|
2632
3140
|
export const run = (async () => {
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
3141
|
+
const expressionContext = {
|
|
3142
|
+
message: 'hi',
|
|
3143
|
+
};
|
|
3144
|
+
|
|
3145
|
+
const expression = expressionFactory.create(
|
|
3146
|
+
expressionContext,
|
|
3147
|
+
'`Say ${message}`',
|
|
3148
|
+
);
|
|
3149
|
+
|
|
3150
|
+
try {
|
|
3151
|
+
// Wait until the expression has been resolved (has a value)
|
|
3152
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
3153
|
+
|
|
3154
|
+
console.log("Initial value of '`Say ${message}`':");
|
|
3155
|
+
expression.changed.subscribe((change) => {
|
|
3156
|
+
console.log(change.value);
|
|
3157
|
+
});
|
|
2647
3158
|
|
|
2648
|
-
|
|
2649
|
-
|
|
3159
|
+
console.log(
|
|
3160
|
+
"Value of '`Say ${message}`' after changing message a to 'hello':",
|
|
3161
|
+
);
|
|
3162
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3163
|
+
ignoreInitialValue: true,
|
|
3164
|
+
}).wait(() => {
|
|
3165
|
+
expressionContext.message = 'hello';
|
|
3166
|
+
});
|
|
2650
3167
|
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
3168
|
+
console.log("Final value of '`Say ${message}`':");
|
|
3169
|
+
console.log(expression.value);
|
|
3170
|
+
} finally {
|
|
3171
|
+
// Always dispose of expressions after use.
|
|
3172
|
+
expression.dispose();
|
|
3173
|
+
}
|
|
2657
3174
|
})();
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
3175
|
```
|
|
2661
3176
|
|
|
2662
3177
|
### Typeof expression
|
|
@@ -2664,44 +3179,51 @@ export const run = (async () => {
|
|
|
2664
3179
|
```ts
|
|
2665
3180
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2666
3181
|
import {
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
3182
|
+
IExpressionFactory,
|
|
3183
|
+
RsXExpressionParserInjectionTokens,
|
|
3184
|
+
RsXExpressionParserModule,
|
|
2670
3185
|
} from '@rs-x/expression-parser';
|
|
2671
3186
|
|
|
2672
3187
|
// Load the expression parser module into the injection container
|
|
2673
3188
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2674
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3189
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3190
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
3191
|
+
);
|
|
2675
3192
|
|
|
2676
3193
|
export const run = (async () => {
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
3194
|
+
const expressionContext = {
|
|
3195
|
+
index: 0,
|
|
3196
|
+
a: ['1', 1],
|
|
3197
|
+
};
|
|
3198
|
+
|
|
3199
|
+
const expression = expressionFactory.create(
|
|
3200
|
+
expressionContext,
|
|
3201
|
+
'typeof a[index]',
|
|
3202
|
+
);
|
|
3203
|
+
|
|
3204
|
+
try {
|
|
3205
|
+
// Wait until the expression has been resolved (has a value)
|
|
3206
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
3207
|
+
|
|
3208
|
+
console.log(`Initial value of 'typeof a[index]':`);
|
|
3209
|
+
expression.changed.subscribe((change) => {
|
|
3210
|
+
console.log(change.value);
|
|
3211
|
+
});
|
|
2692
3212
|
|
|
2693
|
-
|
|
2694
|
-
|
|
3213
|
+
console.log(`Value of 'typeof a[index]' after changing 'index' to '1':`);
|
|
3214
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3215
|
+
ignoreInitialValue: true,
|
|
3216
|
+
}).wait(() => {
|
|
3217
|
+
expressionContext.index = 1;
|
|
3218
|
+
});
|
|
2695
3219
|
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
3220
|
+
console.log(`Final value of 'typeof a[index]':`);
|
|
3221
|
+
console.log(expression.value);
|
|
3222
|
+
} finally {
|
|
3223
|
+
// Always dispose of expressions after use.
|
|
3224
|
+
expression.dispose();
|
|
3225
|
+
}
|
|
2702
3226
|
})();
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
3227
|
```
|
|
2706
3228
|
|
|
2707
3229
|
### Unary negation expression
|
|
@@ -2709,43 +3231,47 @@ export const run = (async () => {
|
|
|
2709
3231
|
```ts
|
|
2710
3232
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2711
3233
|
import {
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
3234
|
+
IExpressionFactory,
|
|
3235
|
+
RsXExpressionParserInjectionTokens,
|
|
3236
|
+
RsXExpressionParserModule,
|
|
2715
3237
|
} from '@rs-x/expression-parser';
|
|
2716
3238
|
|
|
2717
3239
|
// Load the expression parser module into the injection container
|
|
2718
3240
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2719
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3241
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3242
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
3243
|
+
);
|
|
2720
3244
|
|
|
2721
3245
|
export const run = (async () => {
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
3246
|
+
const expressionContext = {
|
|
3247
|
+
value: 1,
|
|
3248
|
+
};
|
|
2725
3249
|
|
|
2726
|
-
|
|
3250
|
+
const expression = expressionFactory.create(expressionContext, '-value');
|
|
2727
3251
|
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
3252
|
+
try {
|
|
3253
|
+
// Wait until the expression has been resolved (has a value)
|
|
3254
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2731
3255
|
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
3256
|
+
console.log(`Initial value of '-value':`);
|
|
3257
|
+
expression.changed.subscribe((change) => {
|
|
3258
|
+
console.log(change.value);
|
|
3259
|
+
});
|
|
2736
3260
|
|
|
2737
|
-
|
|
2738
|
-
|
|
3261
|
+
console.log(`Value of '-value' after changing 'value' to '-5':`);
|
|
3262
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3263
|
+
ignoreInitialValue: true,
|
|
3264
|
+
}).wait(() => {
|
|
3265
|
+
expressionContext.value = -5;
|
|
3266
|
+
});
|
|
2739
3267
|
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
3268
|
+
console.log(`Final value of '-value':`);
|
|
3269
|
+
console.log(expression.value);
|
|
3270
|
+
} finally {
|
|
3271
|
+
// Always dispose of expressions after use.
|
|
3272
|
+
expression.dispose();
|
|
3273
|
+
}
|
|
2746
3274
|
})();
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
3275
|
```
|
|
2750
3276
|
|
|
2751
3277
|
### Unary plus expression
|
|
@@ -2753,41 +3279,45 @@ export const run = (async () => {
|
|
|
2753
3279
|
```ts
|
|
2754
3280
|
import { emptyFunction, InjectionContainer, WaitForEvent } from '@rs-x/core';
|
|
2755
3281
|
import {
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
3282
|
+
IExpressionFactory,
|
|
3283
|
+
RsXExpressionParserInjectionTokens,
|
|
3284
|
+
RsXExpressionParserModule,
|
|
2759
3285
|
} from '@rs-x/expression-parser';
|
|
2760
3286
|
|
|
2761
3287
|
// Load the expression parser module into the injection container
|
|
2762
3288
|
InjectionContainer.load(RsXExpressionParserModule);
|
|
2763
|
-
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3289
|
+
const expressionFactory: IExpressionFactory = InjectionContainer.get(
|
|
3290
|
+
RsXExpressionParserInjectionTokens.IExpressionFactory,
|
|
3291
|
+
);
|
|
2764
3292
|
|
|
2765
3293
|
export const run = (async () => {
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
3294
|
+
const expressionContext = {
|
|
3295
|
+
value: '2',
|
|
3296
|
+
};
|
|
2769
3297
|
|
|
2770
|
-
|
|
3298
|
+
const expression = expressionFactory.create(expressionContext, '+value');
|
|
2771
3299
|
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
3300
|
+
try {
|
|
3301
|
+
// Wait until the expression has been resolved (has a value)
|
|
3302
|
+
await new WaitForEvent(expression, 'changed').wait(emptyFunction);
|
|
2775
3303
|
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
3304
|
+
console.log(`Initial value of '+value':`);
|
|
3305
|
+
expression.changed.subscribe((change) => {
|
|
3306
|
+
console.log(change.value);
|
|
3307
|
+
});
|
|
2780
3308
|
|
|
2781
|
-
|
|
2782
|
-
|
|
3309
|
+
console.log(`Value of '+value' after changing 'value' to '"6"':`);
|
|
3310
|
+
await new WaitForEvent(expression, 'changed', {
|
|
3311
|
+
ignoreInitialValue: true,
|
|
3312
|
+
}).wait(() => {
|
|
3313
|
+
expressionContext.value = '6';
|
|
3314
|
+
});
|
|
2783
3315
|
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
3316
|
+
console.log(`Final value of '+value':`);
|
|
3317
|
+
console.log(expression.value);
|
|
3318
|
+
} finally {
|
|
3319
|
+
// Always dispose of expressions after use.
|
|
3320
|
+
expression.dispose();
|
|
3321
|
+
}
|
|
2790
3322
|
})();
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
```
|
|
3323
|
+
```
|