diff --git a/src/modules/Elsa.JavaScript/Extensions/EngineExtensions.cs b/src/modules/Elsa.JavaScript/Extensions/EngineExtensions.cs
index 9589b2fce..b12b9f449 100644
--- a/src/modules/Elsa.JavaScript/Extensions/EngineExtensions.cs
+++ b/src/modules/Elsa.JavaScript/Extensions/EngineExtensions.cs
@@ -1,5 +1,8 @@
+using Elsa.JavaScript.Helpers;
+using Elsa.JavaScript.Options;
using Jint;
using Jint.Runtime.Interop;
+using Microsoft.Extensions.Options;
// ReSharper disable once CheckNamespace
namespace Elsa.Extensions;
@@ -18,4 +21,15 @@ public static class EngineExtensions
/// Register the specified type T with the engine.
///
public static void RegisterType(this Engine engine, Type type) => engine.SetValue(type.Name, TypeReference.CreateTypeReference(engine, type));
+
+ internal static void SyncVariablesContainer(this Engine engine, IOptions options, string name, object? value)
+ {
+ if (!options.Value.DisableWrappers)
+ {
+ // To ensure both variable accessor syntaxes work, we need to update the variables container in the engine as well as the context to keep them in sync.
+ var variablesContainer = (IDictionary)engine.GetValue("variables").ToObject()!;
+ variablesContainer[name] = ObjectConverterHelper.ProcessVariableValue(engine, value);
+ engine.SetValue("variables", variablesContainer);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithCommonFunctions.cs b/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithCommonFunctions.cs
index 1eee959c6..3c9295288 100644
--- a/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithCommonFunctions.cs
+++ b/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithCommonFunctions.cs
@@ -5,9 +5,12 @@ using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Text.Unicode;
using Elsa.Extensions;
+using Elsa.JavaScript.Helpers;
using Elsa.JavaScript.Notifications;
+using Elsa.JavaScript.Options;
using Elsa.Mediator.Contracts;
using JetBrains.Annotations;
+using Microsoft.Extensions.Options;
namespace Elsa.JavaScript.Handlers;
@@ -15,7 +18,7 @@ namespace Elsa.JavaScript.Handlers;
/// A handler that configures the Jint engine with common functions.
///
[UsedImplicitly]
-public class ConfigureEngineWithCommonFunctions : INotificationHandler
+public class ConfigureEngineWithCommonFunctions(IOptions options) : INotificationHandler
{
private readonly JsonSerializerOptions _jsonSerializerOptions = CreateJsonSerializerOptions();
@@ -32,7 +35,11 @@ public class ConfigureEngineWithCommonFunctions : INotificationHandler)(() => context.GetActivityExecutionContext().WorkflowExecutionContext.Id));
engine.SetValue("setCorrelationId", (Action)(value => context.GetActivityExecutionContext().WorkflowExecutionContext.CorrelationId = value));
engine.SetValue("getCorrelationId", (Func)(() => context.GetActivityExecutionContext().WorkflowExecutionContext.CorrelationId));
- engine.SetValue("setVariable", (Action)((name, value) => context.SetVariableInScope(name, value)));
+ engine.SetValue("setVariable", (Action)((name, value) =>
+ {
+ engine.SyncVariablesContainer(options, name, value);
+ context.SetVariableInScope(name, value);
+ }));
engine.SetValue("getVariable", (Func)(name => context.GetVariableInScope(name)));
engine.SetValue("getInput", (Func)(name => context.GetInput(name)));
engine.SetValue("getOutputFrom", (Func)((activityIdName, outputName) => context.GetOutput(activityIdName, outputName)));
diff --git a/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariables.cs b/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariables.cs
index 57174a43a..76d4926c0 100644
--- a/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariables.cs
+++ b/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariables.cs
@@ -23,18 +23,18 @@ public class ConfigureEngineWithVariables(IOptions options) : INoti
///
public Task HandleAsync(EvaluatingJavaScript notification, CancellationToken cancellationToken)
{
- if(options.Value.DisableWrappers)
+ if (options.Value.DisableWrappers)
return Task.CompletedTask;
-
+
CopyVariablesIntoEngine(notification);
return Task.CompletedTask;
}
public Task HandleAsync(EvaluatedJavaScript notification, CancellationToken cancellationToken)
{
- if(options.Value.DisableWrappers)
+ if (options.Value.DisableWrappers)
return Task.CompletedTask;
-
+
CopyVariablesIntoWorkflowExecutionContext(notification);
return Task.CompletedTask;
}
@@ -56,6 +56,23 @@ public class ConfigureEngineWithVariables(IOptions options) : INoti
}
}
+ private void CopyVariablesIntoEngine(EvaluatingJavaScript notification)
+ {
+ var engine = notification.Engine;
+ var context = notification.Context;
+ var variableNames = context.GetVariableNamesInScope().FilterInvalidVariableNames().ToList();
+ var variablesContainer = (IDictionary)new ExpandoObject();
+
+ foreach (var variableName in variableNames)
+ {
+ var variableValue = context.GetVariableInScope(variableName);
+ variableValue = ObjectConverterHelper.ProcessVariableValue(engine, variableValue);
+ variablesContainer[variableName] = variableValue;
+ }
+
+ engine.SetValue("variables", variablesContainer);
+ }
+
private IEnumerable GetInputNames(ExpressionExecutionContext context)
{
var activityExecutionContext = context.TryGetActivityExecutionContext(out var aec) ? aec : null;
@@ -73,32 +90,4 @@ public class ConfigureEngineWithVariables(IOptions options) : INoti
activityExecutionContext = activityExecutionContext.ParentActivityExecutionContext;
}
}
-
- private void CopyVariablesIntoEngine(EvaluatingJavaScript notification)
- {
- var engine = notification.Engine;
- var context = notification.Context;
- var variableNames = context.GetVariableNamesInScope().FilterInvalidVariableNames().ToList();
- var variablesContainer = (IDictionary)new ExpandoObject();
-
- foreach (var variableName in variableNames)
- {
- var variableValue = context.GetVariableInScope(variableName);
- variableValue = ProcessVariableValue(engine, variableValue);
- variablesContainer[variableName] = variableValue;
- }
-
- engine.SetValue("variables", variablesContainer);
- }
-
- private object? ProcessVariableValue(Engine engine, object? variableValue)
- {
- if (variableValue == null)
- return null;
-
- if (variableValue is not ExpandoObject expandoObject)
- return variableValue;
-
- return ObjectConverterHelper.ConvertToJsObject(engine, expandoObject);
- }
}
\ No newline at end of file
diff --git a/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariablesAndInputOutputAccessors.cs b/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariablesAndInputOutputAccessors.cs
index f0a810625..c64611074 100644
--- a/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariablesAndInputOutputAccessors.cs
+++ b/src/modules/Elsa.JavaScript/Handlers/ConfigureEngineWithVariablesAndInputOutputAccessors.cs
@@ -21,12 +21,12 @@ public class ConfigureEngineWithVariablesAndInputOutputAccessors(IOptions
public async Task HandleAsync(EvaluatingJavaScript notification, CancellationToken cancellationToken)
{
- if(options.Value.DisableWrappers)
+ if (options.Value.DisableWrappers)
return;
-
+
var engine = notification.Engine;
var context = notification.Context;
-
+
// The order of the next 3 lines is important.
CreateVariableAccessors(engine, context);
CreateWorkflowInputAccessors(engine, context);
@@ -41,7 +41,11 @@ public class ConfigureEngineWithVariablesAndInputOutputAccessors(IOptions)(() => context.GetVariableInScope(variableName)));
- engine.SetValue($"set{pascalName}", (Action