mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-13 15:52:56 +01:00
new code editor
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const difference = require('lodash.difference');
|
||||
|
||||
//const Model = require('./data/model');
|
||||
const ExpressionEvaluator = require('../../expression-evaluator');
|
||||
|
||||
const ExpressionNode = {
|
||||
name: 'Expression',
|
||||
@@ -26,6 +25,19 @@ const ExpressionNode = {
|
||||
internal.compiledFunction = undefined;
|
||||
internal.inputNames = [];
|
||||
internal.inputValues = [];
|
||||
|
||||
// New: Expression evaluator integration
|
||||
internal.noodlDependencies = { variables: [], objects: [], arrays: [] };
|
||||
internal.unsubscribe = null;
|
||||
},
|
||||
methods: {
|
||||
_onNodeDeleted: function () {
|
||||
// Clean up reactive subscriptions to prevent memory leaks
|
||||
if (this._internal.unsubscribe) {
|
||||
this._internal.unsubscribe();
|
||||
this._internal.unsubscribe = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
getInspectInfo() {
|
||||
return this._internal.cachedValue;
|
||||
@@ -72,15 +84,31 @@ const ExpressionNode = {
|
||||
self._inputValues[name] = 0;
|
||||
});
|
||||
|
||||
/* if(value.indexOf('Vars') !== -1 || value.indexOf('Variables') !== -1) {
|
||||
// This expression is using variables, it should listen for changes
|
||||
this._internal.onVariablesChangedCallback = (args) => {
|
||||
this._scheduleEvaluateExpression()
|
||||
}
|
||||
// Detect dependencies for reactive updates
|
||||
internal.noodlDependencies = ExpressionEvaluator.detectDependencies(value);
|
||||
|
||||
Model.get('--ndl--global-variables').off('change',this._internal.onVariablesChangedCallback)
|
||||
Model.get('--ndl--global-variables').on('change',this._internal.onVariablesChangedCallback)
|
||||
}*/
|
||||
// Clean up old subscription
|
||||
if (internal.unsubscribe) {
|
||||
internal.unsubscribe();
|
||||
internal.unsubscribe = null;
|
||||
}
|
||||
|
||||
// Subscribe to Noodl global changes if expression uses them
|
||||
if (
|
||||
internal.noodlDependencies.variables.length > 0 ||
|
||||
internal.noodlDependencies.objects.length > 0 ||
|
||||
internal.noodlDependencies.arrays.length > 0
|
||||
) {
|
||||
internal.unsubscribe = ExpressionEvaluator.subscribeToChanges(
|
||||
internal.noodlDependencies,
|
||||
function () {
|
||||
if (!self.isInputConnected('run')) {
|
||||
self._scheduleEvaluateExpression();
|
||||
}
|
||||
},
|
||||
self.context && self.context.modelScope
|
||||
);
|
||||
}
|
||||
|
||||
internal.inputNames = Object.keys(internal.scope);
|
||||
if (!this.isInputConnected('run')) this._scheduleEvaluateExpression();
|
||||
@@ -141,6 +169,33 @@ const ExpressionNode = {
|
||||
group: 'Events',
|
||||
type: 'signal',
|
||||
displayName: 'On False'
|
||||
},
|
||||
// New typed outputs for better downstream compatibility
|
||||
asString: {
|
||||
group: 'Typed Results',
|
||||
type: 'string',
|
||||
displayName: 'As String',
|
||||
getter: function () {
|
||||
const val = this._internal.cachedValue;
|
||||
return val !== undefined && val !== null ? String(val) : '';
|
||||
}
|
||||
},
|
||||
asNumber: {
|
||||
group: 'Typed Results',
|
||||
type: 'number',
|
||||
displayName: 'As Number',
|
||||
getter: function () {
|
||||
const val = this._internal.cachedValue;
|
||||
return typeof val === 'number' ? val : Number(val) || 0;
|
||||
}
|
||||
},
|
||||
asBoolean: {
|
||||
group: 'Typed Results',
|
||||
type: 'boolean',
|
||||
displayName: 'As Boolean',
|
||||
getter: function () {
|
||||
return !!this._internal.cachedValue;
|
||||
}
|
||||
}
|
||||
},
|
||||
prototypeExtensions: {
|
||||
@@ -235,8 +290,19 @@ var functionPreamble = [
|
||||
' floor = Math.floor,' +
|
||||
' ceil = Math.ceil,' +
|
||||
' abs = Math.abs,' +
|
||||
' random = Math.random;'
|
||||
/* ' Vars = Variables = Noodl.Object.get("--ndl--global-variables");' */
|
||||
' random = Math.random,' +
|
||||
' pow = Math.pow,' +
|
||||
' log = Math.log,' +
|
||||
' exp = Math.exp;' +
|
||||
// Add Noodl global context
|
||||
'try {' +
|
||||
' var NoodlContext = (typeof Noodl !== "undefined") ? Noodl : (typeof global !== "undefined" && global.Noodl) || {};' +
|
||||
' var Variables = NoodlContext.Variables || {};' +
|
||||
' var Objects = NoodlContext.Objects || {};' +
|
||||
' var Arrays = NoodlContext.Arrays || {};' +
|
||||
'} catch (e) {' +
|
||||
' var Variables = {}, Objects = {}, Arrays = {};' +
|
||||
'}'
|
||||
].join('');
|
||||
|
||||
//Since apply cannot be used on constructors (i.e. new Something) we need this hax
|
||||
@@ -264,11 +330,19 @@ var portsToIgnore = [
|
||||
'ceil',
|
||||
'abs',
|
||||
'random',
|
||||
'pow',
|
||||
'log',
|
||||
'exp',
|
||||
'Math',
|
||||
'window',
|
||||
'document',
|
||||
'undefined',
|
||||
'Vars',
|
||||
'Variables',
|
||||
'Objects',
|
||||
'Arrays',
|
||||
'Noodl',
|
||||
'NoodlContext',
|
||||
'true',
|
||||
'false',
|
||||
'null',
|
||||
@@ -326,13 +400,43 @@ function updatePorts(nodeId, expression, editorConnection) {
|
||||
}
|
||||
|
||||
function evalCompileWarnings(editorConnection, node) {
|
||||
try {
|
||||
new Function(node.parameters.expression);
|
||||
const expression = node.parameters.expression;
|
||||
if (!expression) {
|
||||
editorConnection.clearWarning(node.component.name, node.id, 'expression-compile-error');
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate expression syntax
|
||||
const validation = ExpressionEvaluator.validateExpression(expression);
|
||||
|
||||
if (!validation.valid) {
|
||||
editorConnection.sendWarning(node.component.name, node.id, 'expression-compile-error', {
|
||||
message: e.message
|
||||
message: 'Syntax error: ' + validation.error
|
||||
});
|
||||
} else {
|
||||
editorConnection.clearWarning(node.component.name, node.id, 'expression-compile-error');
|
||||
|
||||
// Optionally show detected dependencies as info (helpful for users)
|
||||
const deps = ExpressionEvaluator.detectDependencies(expression);
|
||||
const depCount = deps.variables.length + deps.objects.length + deps.arrays.length;
|
||||
|
||||
if (depCount > 0) {
|
||||
const depList = [];
|
||||
if (deps.variables.length > 0) {
|
||||
depList.push('Variables: ' + deps.variables.join(', '));
|
||||
}
|
||||
if (deps.objects.length > 0) {
|
||||
depList.push('Objects: ' + deps.objects.join(', '));
|
||||
}
|
||||
if (deps.arrays.length > 0) {
|
||||
depList.push('Arrays: ' + deps.arrays.join(', '));
|
||||
}
|
||||
|
||||
// This is just informational, not an error
|
||||
// Could be shown in a future info panel
|
||||
// For now, we'll just log it
|
||||
console.log('[Expression Node] Reactive dependencies detected:', depList.join('; '));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user