diff --git a/src/modules/Elsa.Expressions.JavaScript/Handlers/ConfigureEngineWithVariables.cs b/src/modules/Elsa.Expressions.JavaScript/Handlers/ConfigureEngineWithVariables.cs index 13400e509..042e43eb9 100644 --- a/src/modules/Elsa.Expressions.JavaScript/Handlers/ConfigureEngineWithVariables.cs +++ b/src/modules/Elsa.Expressions.JavaScript/Handlers/ConfigureEngineWithVariables.cs @@ -46,7 +46,13 @@ public partial class ConfigureEngineWithVariables(IOptions options) var context = notification.Context; var engine = notification.Engine; var variablesContainer = (IDictionary)engine.GetValue("variables").ToObject()!; - var inputNames = GetInputNames(context).FilterInvalidVariableNames().Distinct().ToList(); + + // Only the variables the expression actually referenced were copied in, so an expression that never + // mentions "variables." has nothing to copy back and does not need the input names resolved at all. + if (variablesContainer.Count == 0) + return; + + var inputNames = GetInputNames(context).FilterInvalidVariableNames().ToHashSet(StringComparer.Ordinal); foreach (var (variableName, variableValue) in variablesContainer) { diff --git a/src/modules/Elsa.Expressions.JavaScript/Helpers/ObjectConverterHelper.cs b/src/modules/Elsa.Expressions.JavaScript/Helpers/ObjectConverterHelper.cs index 28d9ecdcc..e3e2a8282 100644 --- a/src/modules/Elsa.Expressions.JavaScript/Helpers/ObjectConverterHelper.cs +++ b/src/modules/Elsa.Expressions.JavaScript/Helpers/ObjectConverterHelper.cs @@ -1,19 +1,14 @@ using System.Collections; using System.Dynamic; using Elsa.Extensions; -using Elsa.Expressions.JavaScript.Options; using Jint; using Jint.Native; using Jint.Native.Object; -using Jint.Runtime.Descriptors; -using Microsoft.Extensions.Options; namespace Elsa.Expressions.JavaScript.Helpers; internal static class ObjectConverterHelper { - - public static object? ProcessVariableValue(Engine engine, object? variableValue) { if (variableValue == null) @@ -31,10 +26,9 @@ internal static class ObjectConverterHelper foreach (var kvp in expando) { - var value = kvp.Value; - var jsValue = ConvertToJsValue(engine, value); - var propertyDescriptor = new PropertyDescriptor(jsValue, true, true, true); - jsObject.DefineOwnProperty(kvp.Key, propertyDescriptor); + // CreateDataProperty defines a writable, enumerable and configurable property, which is what the + // explicit descriptor used to spell out, and takes the engine's fast path for doing so. + jsObject.CreateDataProperty(kvp.Key, ConvertToJsValue(engine, kvp.Value)); } return jsObject; diff --git a/src/modules/Elsa.Expressions.JavaScript/Services/JintJavaScriptEvaluator.cs b/src/modules/Elsa.Expressions.JavaScript/Services/JintJavaScriptEvaluator.cs index bbc395fc6..15c1818cb 100644 --- a/src/modules/Elsa.Expressions.JavaScript/Services/JintJavaScriptEvaluator.cs +++ b/src/modules/Elsa.Expressions.JavaScript/Services/JintJavaScriptEvaluator.cs @@ -1,6 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using System.Security.Cryptography; -using System.Text; using Acornima.Ast; using Elsa.Expressions.Helpers; using Elsa.Expressions.Models; @@ -25,6 +23,9 @@ namespace Elsa.Expressions.JavaScript.Services; public class JintJavaScriptEvaluator(IConfiguration configuration, INotificationSender mediator, IOptions scriptOptions, IMemoryCache memoryCache) : IJavaScriptEvaluator { + // The converters are stateless, so a single instance of each can serve every engine. + private static readonly IObjectConverter[] ObjectConverters = [new ByteArrayConverter(), new EnumToStringConverter(), new JsonElementConverter()]; + private readonly JintOptions _jintOptions = scriptOptions.Value; /// @@ -97,7 +98,7 @@ public class JintJavaScriptEvaluator(IConfiguration configuration, INotification private void ConfigureObjectConverters(Jint.Options options) { - options.Interop.ObjectConverters.AddRange([new ByteArrayConverter(), new EnumToStringConverter(), new JsonElementConverter()]); + options.Interop.ObjectConverters.AddRange(ObjectConverters); } private void ConfigureArgumentGetters(Engine engine, ExpressionEvaluatorOptions options) @@ -124,15 +125,24 @@ public class JintJavaScriptEvaluator(IConfiguration configuration, INotification private Prepared