ultravisor 1.3.19 → 1.3.21
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/package.json +8 -8
- package/source/services/Ultravisor-Beacon-Coordinator.cjs +124 -13
- package/source/services/Ultravisor-ExecutionEngine.cjs +10 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskConfigs-DataTransform.cjs +11 -1
- package/source/services/tasks/extension/Ultravisor-TaskConfigs-Extension.cjs +5 -2
- package/source/services/tasks/flow-control/Ultravisor-TaskConfigs-FlowControl.cjs +15 -1
- package/source/services/tasks/flow-control/Ultravisor-TaskType-IfConditional.cjs +15 -1
- package/source/services/tasks/user-interaction/Ultravisor-TaskConfigs-UserInteraction.cjs +3 -3
- package/source/services/tasks/user-interaction/Ultravisor-TaskType-ValueInput.cjs +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultravisor",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.21",
|
|
4
4
|
"description": "Cyclic process execution with ai integration.",
|
|
5
5
|
"main": "source/Ultravisor.cjs",
|
|
6
6
|
"bin": {
|
|
@@ -55,18 +55,18 @@
|
|
|
55
55
|
"homepage": "https://github.com/stevenvelozo/ultravisor#readme",
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"cron": "^4.4.0",
|
|
58
|
-
"meadow": "^2.0.
|
|
58
|
+
"meadow": "^2.0.44",
|
|
59
59
|
"meadow-connection-sqlite": "^1.0.20",
|
|
60
|
-
"meadow-migrationmanager": "^1.0.
|
|
60
|
+
"meadow-migrationmanager": "^1.0.5",
|
|
61
61
|
"orator": "^6.1.2",
|
|
62
|
-
"orator-authentication": "^1.0.
|
|
62
|
+
"orator-authentication": "^1.0.6",
|
|
63
63
|
"orator-serviceserver-restify": "^2.0.11",
|
|
64
|
-
"pict": "^1.0.
|
|
65
|
-
"pict-service-commandlineutility": "^1.0.
|
|
64
|
+
"pict": "^1.0.381",
|
|
65
|
+
"pict-service-commandlineutility": "^1.0.20",
|
|
66
66
|
"pict-serviceproviderbase": "^1.0.4",
|
|
67
|
-
"ultravisor-beacon": "^1.0.
|
|
67
|
+
"ultravisor-beacon": "^1.0.5",
|
|
68
68
|
"ultravisor-file-stream": "^1.0.0",
|
|
69
|
-
"ws": "^8.
|
|
69
|
+
"ws": "^8.21.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"pict-docuserve": "^1.4.19",
|
|
@@ -640,8 +640,10 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
640
640
|
|
|
641
641
|
// Add standard beacon dispatch settings
|
|
642
642
|
tmpSettingsInputs.push({ Name: 'AffinityKey', DataType: 'String', Required: false, Description: 'Sticky routing key for beacon affinity.' });
|
|
643
|
+
tmpSettingsInputs.push({ Name: 'RequireAffinityMatch', DataType: 'Boolean', Required: false, Description: 'Strict routing: AffinityKey must match a registered beacon Name; the item waits for that beacon instead of falling back to any capable one.' });
|
|
643
644
|
tmpSettingsInputs.push({ Name: 'TimeoutMs', DataType: 'Number', Required: false, Description: 'Work item timeout in milliseconds.' });
|
|
644
645
|
tmpDefaultSettings.AffinityKey = '';
|
|
646
|
+
tmpDefaultSettings.RequireAffinityMatch = false;
|
|
645
647
|
tmpDefaultSettings.TimeoutMs = 300000;
|
|
646
648
|
|
|
647
649
|
// Derive a display name from the action
|
|
@@ -713,6 +715,7 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
713
715
|
// Build settings object from resolved settings, excluding beacon dispatch meta-fields
|
|
714
716
|
let tmpSettings = Object.assign({}, pResolvedSettings);
|
|
715
717
|
delete tmpSettings.AffinityKey;
|
|
718
|
+
delete tmpSettings.RequireAffinityMatch;
|
|
716
719
|
delete tmpSettings.TimeoutMs;
|
|
717
720
|
|
|
718
721
|
// Coerce types based on schema
|
|
@@ -742,6 +745,7 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
742
745
|
Action: pAction,
|
|
743
746
|
Settings: tmpSettings,
|
|
744
747
|
AffinityKey: pResolvedSettings.AffinityKey || '',
|
|
748
|
+
RequireAffinityMatch: !!pResolvedSettings.RequireAffinityMatch,
|
|
745
749
|
TimeoutMs: pResolvedSettings.TimeoutMs || 300000
|
|
746
750
|
}, pExecutionContext, fCallback);
|
|
747
751
|
};
|
|
@@ -1115,6 +1119,7 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
1115
1119
|
Action: pWorkItemInfo.Action || 'Execute',
|
|
1116
1120
|
Settings: tmpSettings,
|
|
1117
1121
|
AffinityKey: pWorkItemInfo.AffinityKey || '',
|
|
1122
|
+
RequireAffinityMatch: !!pWorkItemInfo.RequireAffinityMatch,
|
|
1118
1123
|
AssignedBeaconID: null,
|
|
1119
1124
|
Status: 'Pending',
|
|
1120
1125
|
TimeoutMs: pWorkItemInfo.TimeoutMs || tmpDefaultTimeout,
|
|
@@ -1176,6 +1181,14 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
1176
1181
|
tmpNamedBeacon.CurrentWorkItems.push(tmpWorkItemHash);
|
|
1177
1182
|
this.log.info(`BeaconCoordinator: work item [${tmpWorkItemHash}] routed by name to beacon [${tmpNamedBeacon.BeaconID}] (Name=${tmpNamedBeacon.Name}) via AffinityKey [${tmpWorkItem.AffinityKey}].`);
|
|
1178
1183
|
}
|
|
1184
|
+
else if (tmpWorkItem.RequireAffinityMatch)
|
|
1185
|
+
{
|
|
1186
|
+
// Strict routing: the designated beacon is not registered right
|
|
1187
|
+
// now (offline / mid-restart). The item stays Pending and only
|
|
1188
|
+
// that beacon may claim it when it returns — never another
|
|
1189
|
+
// capable beacon. The normal work-item timeout bounds the wait.
|
|
1190
|
+
this.log.warn(`BeaconCoordinator: work item [${tmpWorkItemHash}] requires beacon [${tmpWorkItem.AffinityKey}], which is not registered — holding pending until it returns.`);
|
|
1191
|
+
}
|
|
1179
1192
|
else
|
|
1180
1193
|
{
|
|
1181
1194
|
let tmpBinding = this._AffinityBindings[tmpWorkItem.AffinityKey];
|
|
@@ -1275,23 +1288,101 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
1275
1288
|
}
|
|
1276
1289
|
else if (tmpWorkItem.Status === 'Assigned' && tmpWorkItem.AssignedBeaconID && this._WorkItemPushHandler)
|
|
1277
1290
|
{
|
|
1278
|
-
// Affinity pre-assigned — push directly to the assigned beacon via
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1291
|
+
// Affinity pre-assigned — push directly to the assigned beacon via
|
|
1292
|
+
// WebSocket, but only within the beacon's RUNNING capacity. The
|
|
1293
|
+
// beacon SDK silently drops frames beyond its concurrency, so an
|
|
1294
|
+
// ungated burst loses work items (they sit "Running" until the
|
|
1295
|
+
// direct-dispatch timeout while the beacon never saw them).
|
|
1296
|
+
// Over-capacity items stay Assigned; the slot-free re-dispatch in
|
|
1297
|
+
// _dispatchPendingWorkItems delivers them as completions land.
|
|
1298
|
+
this._pushAssignedWorkItem(tmpWorkItem);
|
|
1299
|
+
}
|
|
1282
1300
|
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1301
|
+
return tmpWorkItem;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/**
|
|
1305
|
+
* Push an Assigned work item to its designated WebSocket beacon when the
|
|
1306
|
+
* beacon has Running capacity. Leaves the item Assigned (HTTP-poll
|
|
1307
|
+
* claimable, slot-free re-deliverable) when the beacon is full, offline,
|
|
1308
|
+
* or the push fails.
|
|
1309
|
+
*
|
|
1310
|
+
* @param {object} pWorkItem
|
|
1311
|
+
* @returns {boolean} True when the item was delivered.
|
|
1312
|
+
*/
|
|
1313
|
+
_pushAssignedWorkItem(pWorkItem)
|
|
1314
|
+
{
|
|
1315
|
+
if (!this._WorkItemPushHandler || !pWorkItem.AssignedBeaconID)
|
|
1316
|
+
{
|
|
1317
|
+
return false;
|
|
1318
|
+
}
|
|
1319
|
+
let tmpBeacon = this._Beacons[pWorkItem.AssignedBeaconID];
|
|
1320
|
+
if (!tmpBeacon || (tmpBeacon.Status !== 'Online' && tmpBeacon.Status !== 'Busy'))
|
|
1321
|
+
{
|
|
1322
|
+
return false;
|
|
1323
|
+
}
|
|
1324
|
+
let tmpMaxConcurrent = tmpBeacon.MaxConcurrent || 1;
|
|
1325
|
+
if (this._runningCountForBeacon(pWorkItem.AssignedBeaconID) >= tmpMaxConcurrent)
|
|
1326
|
+
{
|
|
1327
|
+
this.log.info(`BeaconCoordinator: beacon [${pWorkItem.AssignedBeaconID}] at running capacity (${tmpMaxConcurrent}) — holding assigned work item [${pWorkItem.WorkItemHash}] for slot-free delivery.`);
|
|
1328
|
+
return false;
|
|
1329
|
+
}
|
|
1330
|
+
pWorkItem.Status = 'Running';
|
|
1331
|
+
let tmpPushed = this._WorkItemPushHandler(pWorkItem.AssignedBeaconID,
|
|
1332
|
+
this._sanitizeWorkItemForBeacon(pWorkItem));
|
|
1333
|
+
if (tmpPushed)
|
|
1334
|
+
{
|
|
1335
|
+
this.log.info(`BeaconCoordinator: pushed affinity-assigned work item [${pWorkItem.WorkItemHash}] to WebSocket beacon [${pWorkItem.AssignedBeaconID}].`);
|
|
1336
|
+
return true;
|
|
1337
|
+
}
|
|
1338
|
+
pWorkItem.Status = 'Assigned';
|
|
1339
|
+
return false;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
/**
|
|
1343
|
+
* Count work items currently RUNNING on a beacon. CurrentWorkItems
|
|
1344
|
+
* includes Assigned-but-not-yet-delivered items, so it overstates the
|
|
1345
|
+
* beacon's true in-flight load — pushes must be gated on Running only,
|
|
1346
|
+
* or a burst of affinity-assigned items overruns the beacon SDK's
|
|
1347
|
+
* concurrency and the overflow frames are silently dropped.
|
|
1348
|
+
*
|
|
1349
|
+
* @param {string} pBeaconID
|
|
1350
|
+
* @returns {number}
|
|
1351
|
+
*/
|
|
1352
|
+
_runningCountForBeacon(pBeaconID)
|
|
1353
|
+
{
|
|
1354
|
+
let tmpCount = 0;
|
|
1355
|
+
let tmpHashes = Object.keys(this._WorkQueue);
|
|
1356
|
+
for (let i = 0; i < tmpHashes.length; i++)
|
|
1357
|
+
{
|
|
1358
|
+
let tmpWI = this._WorkQueue[tmpHashes[i]];
|
|
1359
|
+
if (tmpWI && tmpWI.AssignedBeaconID === pBeaconID && tmpWI.Status === 'Running')
|
|
1288
1360
|
{
|
|
1289
|
-
|
|
1290
|
-
tmpWorkItem.Status = 'Assigned';
|
|
1361
|
+
tmpCount++;
|
|
1291
1362
|
}
|
|
1292
1363
|
}
|
|
1364
|
+
return tmpCount;
|
|
1365
|
+
}
|
|
1293
1366
|
|
|
1294
|
-
|
|
1367
|
+
/**
|
|
1368
|
+
* Whether a beacon is allowed to take a work item under affinity rules.
|
|
1369
|
+
*
|
|
1370
|
+
* RequireAffinityMatch items designate a beacon BY NAME: only that beacon
|
|
1371
|
+
* may be pushed, polled, or sticky-bound the item. Without the flag,
|
|
1372
|
+
* AffinityKey keeps its dual role (name routing when matched, otherwise a
|
|
1373
|
+
* session-stickiness hint any capable beacon can seed).
|
|
1374
|
+
*
|
|
1375
|
+
* @param {object} pWorkItem
|
|
1376
|
+
* @param {object} pBeacon - a registered beacon record
|
|
1377
|
+
* @returns {boolean}
|
|
1378
|
+
*/
|
|
1379
|
+
_beaconSatisfiesAffinity(pWorkItem, pBeacon)
|
|
1380
|
+
{
|
|
1381
|
+
if (!pWorkItem || !pWorkItem.RequireAffinityMatch || !pWorkItem.AffinityKey)
|
|
1382
|
+
{
|
|
1383
|
+
return true;
|
|
1384
|
+
}
|
|
1385
|
+
return !!(pBeacon && pBeacon.Name === pWorkItem.AffinityKey);
|
|
1295
1386
|
}
|
|
1296
1387
|
|
|
1297
1388
|
/**
|
|
@@ -1328,6 +1419,11 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
1328
1419
|
{
|
|
1329
1420
|
continue;
|
|
1330
1421
|
}
|
|
1422
|
+
if (!this._beaconSatisfiesAffinity(pWorkItem, tmpBeacon))
|
|
1423
|
+
{
|
|
1424
|
+
continue;
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1331
1427
|
if (tmpBeacon.Capabilities.indexOf(pWorkItem.Capability) === -1)
|
|
1332
1428
|
{
|
|
1333
1429
|
continue;
|
|
@@ -1527,6 +1623,12 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
1527
1623
|
continue;
|
|
1528
1624
|
}
|
|
1529
1625
|
|
|
1626
|
+
// Strict affinity: only the designated beacon may claim
|
|
1627
|
+
if (!this._beaconSatisfiesAffinity(tmpWorkItem, tmpBeacon))
|
|
1628
|
+
{
|
|
1629
|
+
continue;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1530
1632
|
// Check capability match
|
|
1531
1633
|
if (tmpBeacon.Capabilities.indexOf(tmpWorkItem.Capability) === -1)
|
|
1532
1634
|
{
|
|
@@ -2089,7 +2191,9 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
2089
2191
|
{
|
|
2090
2192
|
if (tmpContext.WaitingTasks[tmpWorkItem.NodeHash])
|
|
2091
2193
|
{
|
|
2092
|
-
|
|
2194
|
+
// Must exactly match the EventOutputs Name 'Error' — the engine's
|
|
2195
|
+
// downstream-event match is case-sensitive.
|
|
2196
|
+
tmpContext.WaitingTasks[tmpWorkItem.NodeHash].ResumeEventName = 'Error';
|
|
2093
2197
|
}
|
|
2094
2198
|
// Push the failure into the canonical Errors[] log so
|
|
2095
2199
|
// finalizeExecution's roll-up sees it and the operation
|
|
@@ -2668,6 +2772,13 @@ class UltravisorBeaconCoordinator extends libPictService
|
|
|
2668
2772
|
{
|
|
2669
2773
|
let tmpWI = this._WorkQueue[tmpHashes[i]];
|
|
2670
2774
|
if (!tmpWI) continue;
|
|
2775
|
+
if (tmpWI.Status === 'Assigned' && tmpWI.AssignedBeaconID)
|
|
2776
|
+
{
|
|
2777
|
+
// Held back at enqueue because the designated beacon was at
|
|
2778
|
+
// running capacity — deliver as slots free up.
|
|
2779
|
+
this._pushAssignedWorkItem(tmpWI);
|
|
2780
|
+
continue;
|
|
2781
|
+
}
|
|
2671
2782
|
if (tmpWI.Status !== 'Pending') continue;
|
|
2672
2783
|
if (tmpWI.AssignedBeaconID) continue; // affinity-assigned, leave it
|
|
2673
2784
|
this._tryPushToWebSocketBeacon(tmpWI);
|
|
@@ -1541,6 +1541,7 @@ class UltravisorExecutionEngine extends libPictService
|
|
|
1541
1541
|
let tmpConnections = pContext._ConnectionMap.eventSources[pSourceNodeHash] || [];
|
|
1542
1542
|
let tmpPortLabelMap = pContext._PortLabelMap;
|
|
1543
1543
|
|
|
1544
|
+
let tmpMatchedCount = 0;
|
|
1544
1545
|
for (let i = 0; i < tmpConnections.length; i++)
|
|
1545
1546
|
{
|
|
1546
1547
|
let tmpConn = tmpConnections[i];
|
|
@@ -1548,6 +1549,7 @@ class UltravisorExecutionEngine extends libPictService
|
|
|
1548
1549
|
|
|
1549
1550
|
if (tmpSourcePortName === pEventName)
|
|
1550
1551
|
{
|
|
1552
|
+
tmpMatchedCount++;
|
|
1551
1553
|
let tmpTargetPortName = this._extractPortName(tmpConn.TargetPortHash, tmpPortLabelMap);
|
|
1552
1554
|
pContext.PendingEvents.push({
|
|
1553
1555
|
TargetNodeHash: tmpConn.TargetNodeHash,
|
|
@@ -1555,6 +1557,14 @@ class UltravisorExecutionEngine extends libPictService
|
|
|
1555
1557
|
});
|
|
1556
1558
|
}
|
|
1557
1559
|
}
|
|
1560
|
+
|
|
1561
|
+
// An event that matches none of the node's outgoing connections strands
|
|
1562
|
+
// everything downstream while the run can still terminate 'Complete' —
|
|
1563
|
+
// surface it (event-name/port-label matching is case-sensitive).
|
|
1564
|
+
if (tmpConnections.length > 0 && tmpMatchedCount === 0)
|
|
1565
|
+
{
|
|
1566
|
+
this._log(pContext, `Node [${pSourceNodeHash}] fired event [${pEventName}] but none of its ${tmpConnections.length} outgoing event connection(s) match that name — downstream nodes will not run.`, 'warn');
|
|
1567
|
+
}
|
|
1558
1568
|
}
|
|
1559
1569
|
|
|
1560
1570
|
/**
|
|
@@ -421,7 +421,17 @@ module.exports =
|
|
|
421
421
|
{
|
|
422
422
|
try
|
|
423
423
|
{
|
|
424
|
-
|
|
424
|
+
// Fable's ExpressionParser API is solve(expression, dataSource,
|
|
425
|
+
// results, manifest, destination). The data source mirrors the
|
|
426
|
+
// StateManager address roots so expressions can reference
|
|
427
|
+
// Operation.X / Global.X / TaskOutput.<node>.<key> directly.
|
|
428
|
+
tmpResult = pTask.fable.ExpressionParser.solve(tmpExpression,
|
|
429
|
+
{
|
|
430
|
+
Operation: pExecutionContext.OperationState || {},
|
|
431
|
+
Global: pExecutionContext.GlobalState || {},
|
|
432
|
+
TaskOutput: pExecutionContext.TaskOutputs || {}
|
|
433
|
+
},
|
|
434
|
+
{}, pTask.fable.manifest, {});
|
|
425
435
|
}
|
|
426
436
|
catch (pError)
|
|
427
437
|
{
|
|
@@ -131,10 +131,13 @@ module.exports =
|
|
|
131
131
|
pTask.log.info(`Beacon Dispatch: enqueued work item [${tmpWorkItem.WorkItemHash}] for capability [${tmpWorkItemInfo.Capability}/${tmpWorkItemInfo.Action}]` +
|
|
132
132
|
(tmpWorkItemInfo.AffinityKey ? ` with affinity [${tmpWorkItemInfo.AffinityKey}]` : ''));
|
|
133
133
|
|
|
134
|
-
// Pause execution — the BeaconCoordinator will call resumeOperation when the Beacon reports back
|
|
134
|
+
// Pause execution — the BeaconCoordinator will call resumeOperation when the Beacon reports back.
|
|
135
|
+
// ResumeEventName must exactly match an EventOutputs Name ('Complete') — the
|
|
136
|
+
// engine's downstream-event match is case-sensitive, so 'complete' silently
|
|
137
|
+
// strands every node wired after this one.
|
|
135
138
|
return fCallback(null, {
|
|
136
139
|
WaitingForInput: true,
|
|
137
|
-
ResumeEventName: '
|
|
140
|
+
ResumeEventName: 'Complete',
|
|
138
141
|
PromptMessage: `Waiting for Beacon worker (${tmpWorkItemInfo.Capability}/${tmpWorkItemInfo.Action})`,
|
|
139
142
|
OutputAddress: '',
|
|
140
143
|
Outputs: {},
|
|
@@ -211,7 +211,21 @@ module.exports =
|
|
|
211
211
|
{
|
|
212
212
|
if (pTask.fable.ExpressionParser)
|
|
213
213
|
{
|
|
214
|
-
|
|
214
|
+
// Fable's ExpressionParser API is solve(expression, dataSource,
|
|
215
|
+
// results, manifest, destination); the data source mirrors the
|
|
216
|
+
// StateManager address roots. solve returns STRINGS — boolean
|
|
217
|
+
// comparisons come back as '1'/'0', and '0' is truthy in JS,
|
|
218
|
+
// so coerce explicitly before branching.
|
|
219
|
+
let tmpSolved = pTask.fable.ExpressionParser.solve(pResolvedSettings.Expression,
|
|
220
|
+
{
|
|
221
|
+
Operation: pExecutionContext.OperationState || {},
|
|
222
|
+
Global: pExecutionContext.GlobalState || {},
|
|
223
|
+
TaskOutput: pExecutionContext.TaskOutputs || {}
|
|
224
|
+
},
|
|
225
|
+
{}, pTask.fable.manifest, {});
|
|
226
|
+
tmpResult = !(tmpSolved === undefined || tmpSolved === null || tmpSolved === false
|
|
227
|
+
|| tmpSolved === 0 || tmpSolved === '' || tmpSolved === '0'
|
|
228
|
+
|| String(tmpSolved).toLowerCase() === 'false');
|
|
215
229
|
}
|
|
216
230
|
else
|
|
217
231
|
{
|
|
@@ -36,7 +36,21 @@ class UltravisorTaskTypeIfConditional extends libTaskTypeBase
|
|
|
36
36
|
{
|
|
37
37
|
if (this.fable.ExpressionParser)
|
|
38
38
|
{
|
|
39
|
-
|
|
39
|
+
// Fable's ExpressionParser API is solve(expression, dataSource,
|
|
40
|
+
// results, manifest, destination); the data source mirrors the
|
|
41
|
+
// StateManager address roots. solve returns STRINGS — boolean
|
|
42
|
+
// comparisons come back as '1'/'0', and '0' is truthy in JS,
|
|
43
|
+
// so coerce explicitly before branching.
|
|
44
|
+
let tmpSolved = this.fable.ExpressionParser.solve(pResolvedSettings.Expression,
|
|
45
|
+
{
|
|
46
|
+
Operation: pExecutionContext.OperationState || {},
|
|
47
|
+
Global: pExecutionContext.GlobalState || {},
|
|
48
|
+
TaskOutput: pExecutionContext.TaskOutputs || {}
|
|
49
|
+
},
|
|
50
|
+
{}, this.fable.manifest, {});
|
|
51
|
+
tmpResult = !(tmpSolved === undefined || tmpSolved === null || tmpSolved === false
|
|
52
|
+
|| tmpSolved === 0 || tmpSolved === '' || tmpSolved === '0'
|
|
53
|
+
|| String(tmpSolved).toLowerCase() === 'false');
|
|
40
54
|
}
|
|
41
55
|
else
|
|
42
56
|
{
|
|
@@ -106,7 +106,7 @@ module.exports =
|
|
|
106
106
|
if (tmpExistingValue !== undefined && tmpExistingValue !== null && tmpExistingValue !== '')
|
|
107
107
|
{
|
|
108
108
|
return fCallback(null, {
|
|
109
|
-
EventToFire: '
|
|
109
|
+
EventToFire: 'ValueInputComplete',
|
|
110
110
|
Outputs: { InputValue: tmpExistingValue },
|
|
111
111
|
Log: [`Auto-resolved from pre-seeded state: "${tmpOutputAddress}" = "${String(tmpExistingValue).substring(0, 100)}"`]
|
|
112
112
|
});
|
|
@@ -123,7 +123,7 @@ module.exports =
|
|
|
123
123
|
if (tmpIsProgrammatic && tmpDefaultValue !== undefined && tmpDefaultValue !== null && tmpDefaultValue !== '')
|
|
124
124
|
{
|
|
125
125
|
return fCallback(null, {
|
|
126
|
-
EventToFire: '
|
|
126
|
+
EventToFire: 'ValueInputComplete',
|
|
127
127
|
Outputs: { InputValue: tmpDefaultValue },
|
|
128
128
|
Log: [`Auto-resolved from default: "${tmpOutputAddress}" = "${String(tmpDefaultValue).substring(0, 100)}"`]
|
|
129
129
|
});
|
|
@@ -135,7 +135,7 @@ module.exports =
|
|
|
135
135
|
if (tmpIsProgrammatic && tmpIsOptional)
|
|
136
136
|
{
|
|
137
137
|
return fCallback(null, {
|
|
138
|
-
EventToFire: '
|
|
138
|
+
EventToFire: 'ValueInputComplete',
|
|
139
139
|
Outputs: { InputValue: '' },
|
|
140
140
|
Log: [`Auto-resolved optional field: "${tmpOutputAddress}" = "" (no value provided)`]
|
|
141
141
|
});
|
|
@@ -41,7 +41,7 @@ class UltravisorTaskTypeValueInput extends libTaskTypeBase
|
|
|
41
41
|
if (tmpExistingValue !== undefined && tmpExistingValue !== null && tmpExistingValue !== '')
|
|
42
42
|
{
|
|
43
43
|
return fCallback(null, {
|
|
44
|
-
EventToFire: '
|
|
44
|
+
EventToFire: 'ValueInputComplete',
|
|
45
45
|
Outputs: { InputValue: tmpExistingValue },
|
|
46
46
|
Log: [`Auto-resolved from pre-seeded state: "${tmpOutputAddress}" = "${String(tmpExistingValue).substring(0, 100)}"`]
|
|
47
47
|
});
|
|
@@ -59,7 +59,7 @@ class UltravisorTaskTypeValueInput extends libTaskTypeBase
|
|
|
59
59
|
if (tmpIsProgrammatic && tmpDefaultValue !== undefined && tmpDefaultValue !== null && tmpDefaultValue !== '')
|
|
60
60
|
{
|
|
61
61
|
return fCallback(null, {
|
|
62
|
-
EventToFire: '
|
|
62
|
+
EventToFire: 'ValueInputComplete',
|
|
63
63
|
Outputs: { InputValue: tmpDefaultValue },
|
|
64
64
|
Log: [`Auto-resolved from default: "${tmpOutputAddress}" = "${String(tmpDefaultValue).substring(0, 100)}"`]
|
|
65
65
|
});
|
|
@@ -71,7 +71,7 @@ class UltravisorTaskTypeValueInput extends libTaskTypeBase
|
|
|
71
71
|
if (tmpIsProgrammatic && tmpIsOptional)
|
|
72
72
|
{
|
|
73
73
|
return fCallback(null, {
|
|
74
|
-
EventToFire: '
|
|
74
|
+
EventToFire: 'ValueInputComplete',
|
|
75
75
|
Outputs: { InputValue: '' },
|
|
76
76
|
Log: [`Auto-resolved optional field: "${tmpOutputAddress}" = "" (no value provided)`]
|
|
77
77
|
});
|