Skip to content

Commit 07dc294

Browse files
committed
choice restored
1 parent 83b6d8d commit 07dc294

1 file changed

Lines changed: 97 additions & 35 deletions

File tree

‎src/processors/flow/Choice.js‎

Lines changed: 97 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// src/processors/flow/Choice.js
2-
// TODO implement
32

43
import logger from '../../utils/Logger.js'
54
import ns from '../../utils/ns.js'
@@ -9,77 +8,140 @@ import Processor from '../../model/Processor.js'
98
* @class Choice
109
* @extends Processor
1110
* @classdesc
12-
* **a Transmissions Processor**
11+
* **a Transmissions Processor for Conditional Logic**
1312
*
14-
* Processes messages by applying conditional logic and property transformations.
13+
* Evaluates a condition and sets message properties based on the result, enabling
14+
* conditional branching within transmission pipelines.
1515
*
1616
* ### Processor Signature
1717
*
1818
* #### __*Settings*__
19-
* * **`ns.trn.me`** - Identifier for the processor instance
20-
* * **`ns.trn.common`** - Common value to be added to the message
21-
* * **`ns.trn.something1`** - First value to be processed
22-
* * **`ns.trn.something2`** - Second value to be processed
23-
* * **`ns.trn.added`** - Optional string to append to something1
24-
* * **`ns.trn.notavalue`** - Fallback value if not provided in config
19+
* * **`ns.trn.testProperty`** - Property name to test (e.g., "userType", "status")
20+
* * **`ns.trn.testOperator`** - Comparison operator: "equals", "contains", "greater", "less", "exists"
21+
* * **`ns.trn.testValue`** - Value to compare against (for equals, contains, greater, less)
22+
* * **`ns.trn.trueProperty`** - Property to set if condition is true
23+
* * **`ns.trn.trueValue`** - Value to set for true condition
24+
* * **`ns.trn.falseProperty`** - Property to set if condition is false
25+
* * **`ns.trn.falseValue`** - Value to set for false condition
2526
*
2627
* #### __*Input*__
27-
* * **`message`** - The message object to be processed
28+
* * **`message`** - The message object containing properties to test
2829
*
2930
* #### __*Output*__
30-
* * **`message`** - The modified message object with added/updated fields
31+
* * **`message`** - Message with additional properties set based on the choice made
3132
*
3233
* #### __*Behavior*__
33-
* * Forwards message immediately if `message.done` is true
34-
* * Retrieves and processes configuration properties
35-
* * Appends optional values to message fields
36-
* * Handles fallback values for missing properties
34+
* * Skips processing if `message.done` is true
35+
* * Evaluates the specified condition using testProperty, testOperator, and testValue
36+
* * Sets trueProperty=trueValue if condition is true
37+
* * Sets falseProperty=falseValue if condition is false
38+
* * Supports operators: equals, contains, greater, less, exists
39+
* * Enables downstream processors to react to the choice via message properties
3740
*
3841
* #### __*Side Effects*__
39-
* * Modifies the input message object
40-
* * Logs processing information
42+
* * Adds choice result properties to the message object
43+
* * Logs the condition evaluation and choice made
4144
*
42-
* #### __*Tests*__
43-
* * TODO: Add test coverage
45+
* #### __*Example Configuration*__
46+
* ```turtle
47+
* :userRouter a :Choice ;
48+
* :settings :userChoiceConfig .
49+
*
50+
* :userChoiceConfig a :ConfigSet ;
51+
* :testProperty "userType" ;
52+
* :testOperator "equals" ;
53+
* :testValue "premium" ;
54+
* :trueProperty "processingPath" ;
55+
* :trueValue "premium-flow" ;
56+
* :falseProperty "processingPath" ;
57+
* :falseValue "standard-flow" .
58+
* ```
4459
*/
4560
class Choice extends Processor {
4661
constructor(config) {
4762
super(config)
4863
}
4964

5065
/**
51-
* Processes the message by applying property transformations and conditional logic.
66+
* Evaluates a condition and sets message properties based on the result.
5267
* @param {Object} message - The message object to process
5368
* @returns {Promise} Resolves when processing is complete
5469
*/
5570
async process(message) {
56-
logger.debug(`\n\nChoice.process`)
71+
logger.debug(`Choice.process starting`)
5772

58-
// TODO figure this out better
59-
// may be needed if preceded by a spawning processor, eg. fs/DirWalker
73+
// Skip processing if message is marked as done
6074
if (message.done) {
75+
logger.debug(`Choice: Message marked as done, skipping`)
6176
return this.emit('message', message)
62-
// or simply return
6377
}
6478

65-
// message is processed here :
79+
// Get configuration properties
80+
const testProperty = this.getProperty(ns.trn.testProperty)
81+
const testOperator = this.getProperty(ns.trn.testOperator, 'equals')
82+
const testValue = this.getProperty(ns.trn.testValue)
83+
const trueProperty = this.getProperty(ns.trn.trueProperty)
84+
const trueValue = this.getProperty(ns.trn.trueValue)
85+
const falseProperty = this.getProperty(ns.trn.falseProperty)
86+
const falseValue = this.getProperty(ns.trn.falseValue)
6687

67-
// property values pulled from message | config settings | fallback
68-
const me = await this.getProperty(ns.trn.me)
69-
logger.log(`\nI am ${me}`)
88+
if (!testProperty) {
89+
logger.warn(`Choice: No testProperty specified, skipping condition evaluation`)
90+
return this.emit('message', message)
91+
}
7092

71-
message.common = await this.getProperty(ns.trn.common)
72-
message.something1 = await this.getProperty(ns.trn.something1)
93+
// Get the value to test from the message
94+
const messageValue = message[testProperty]
7395

74-
message.something2 = await this.getProperty(ns.trn.something2)
96+
// Evaluate the condition
97+
const conditionResult = this.evaluateCondition(messageValue, testOperator, testValue)
7598

76-
var added = await this.getProperty(ns.trn.added, '')
77-
message.something1 = message.something1 + added
99+
logger.debug(`Choice: ${testProperty}="${messageValue}" ${testOperator} "${testValue}" = ${conditionResult}`)
78100

79-
message.notavalue = await this.getProperty(ns.trn.notavalue, 'fallback value')
101+
// Apply the choice result
102+
if (conditionResult) {
103+
if (trueProperty && trueValue !== undefined) {
104+
message[trueProperty] = trueValue
105+
logger.debug(`Choice: TRUE - Set ${trueProperty}="${trueValue}"`)
106+
}
107+
} else {
108+
if (falseProperty && falseValue !== undefined) {
109+
message[falseProperty] = falseValue
110+
logger.debug(`Choice: FALSE - Set ${falseProperty}="${falseValue}"`)
111+
}
112+
}
80113

81-
// message forwarded
82114
return this.emit('message', message)
83115
}
116+
117+
/**
118+
* Evaluates a condition using the specified operator
119+
* @param {any} messageValue - Value from the message to test
120+
* @param {string} operator - Comparison operator
121+
* @param {any} testValue - Value to compare against
122+
* @returns {boolean} Result of the condition evaluation
123+
*/
124+
evaluateCondition(messageValue, operator, testValue) {
125+
switch (operator.toLowerCase()) {
126+
case 'equals':
127+
return messageValue == testValue
128+
129+
case 'contains':
130+
return String(messageValue || '').includes(String(testValue || ''))
131+
132+
case 'greater':
133+
return Number(messageValue) > Number(testValue)
134+
135+
case 'less':
136+
return Number(messageValue) < Number(testValue)
137+
138+
case 'exists':
139+
return messageValue !== undefined && messageValue !== null && messageValue !== ''
140+
141+
default:
142+
logger.warn(`Choice: Unknown operator "${operator}", defaulting to equals`)
143+
return messageValue == testValue
144+
}
145+
}
84146
}
85147
export default Choice

0 commit comments

Comments
 (0)