Commit graph

27 commits

Author SHA1 Message Date
Marko Lahma 7328a0f14d
Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895)
* chore(javascript): update Jint to 4.15.3 and stop blocking on promises

`Engine.Evaluate(...).UnwrapIfPromise()` blocks the calling thread while the
engine's event loop drains, which is exactly the wrong thing to do inside an
`async` method — an expression that awaits a .NET `Task`, such as one calling
`getSecret()`, held a thread pool thread for the duration of the I/O.
`Engine.EvaluateAsync` awaits the returned promise instead, and takes the
cancellation token while it is at it.

The Jint version is moved from 4.4.2 to 4.15.3. `EvaluateAsync` arrived in
4.14.0, but the pin lands past 4.15.2 deliberately: once expressions genuinely
suspend and resume instead of draining the event loop on the calling thread,
they exercise the async suspension machinery 4.15.2 corrected — an `await` on a
right-hand side no longer stores the suspension sentinel, async generators and
`for await...of` preserve loop iteration state across a suspension, and a
suspension node is unwrapped correctly. Shipping the non-blocking change on an
earlier 4.14/4.15 would enable exactly the code paths those releases fixed.

One default changed along the way: since 4.14 `Interop.ArrayConversion` defaults
to `LiveView`, so a CLR array reaches script as a live view over the original
array rather than as a copy. That is observable — a script that sorts an array
would now reorder the workflow's own array, and the value round-trips back as
its original element type rather than as `object[]`. The evaluator therefore
pins the previous `Copy` behaviour so the upgrade is not a behavioural change;
hosts that prefer the live view can opt in through
`JintOptions.ConfigureEngineOptions`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

* test(javascript): pin the array copy lane and adopt JsString.Create

The array audit. The parent commit fixes `ArrayConversion` to `Copy`, because
4.14 changed the default to `LiveView` and the two differ in behaviour a script
can observe. The existing tests assert what a copy *produces*, which a live view
also satisfies for a value nothing mutates; asking the engine how many
conversions of each kind it performed (4.15.1's interop conversion counters)
pins the lane itself. The second assertion is the more interesting one: an
ordinary evaluation converts no CLR array at all, because Elsa converts
collection-valued variables itself in `ObjectConverterHelper` long before Jint's
array lane could see them. That makes the `ArrayConversion` setting a narrow
compatibility pin rather than something every evaluation depends on.

`JsString.Create` (public since Jint 4.15.3) is adopted in
`JsonElementConverter`, where the string case was the only one still routed
through `JsValue.FromObject` — re-entering the whole conversion pipeline, the
registered object converters and this one included, to arrive at the same call
the number and boolean cases beside it already make directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

* perf(javascript): register .NET type globals lazily

A fresh Jint engine is built for every expression evaluation, and roughly twenty
.NET types are registered on it before the expression runs: the common types
(`DateTime`, `Guid`, `TimeSpan`, …) plus every non-primitive workflow variable
descriptor type. Each registration builds a `TypeReference`, which describes the
type through reflection. The overwhelming majority of expressions reference none
of them.

`Options.AddLazyGlobal` installs a global whose value is produced by a factory
the first time a script reads the name. Both type registration handlers now run
on `CreatingJavaScriptEngine` — which already carries the `Jint.Options` being
built — and register through it, so a type is only described if an expression
actually mentions it. A script that uses `Guid.NewGuid()` still sees `Guid`; a
script that uses none of them pays for none of them.

Types whose name cannot be written as a JavaScript identifier are skipped while
we are here, since no script can reach them. That covers constructed generic
types (``IDictionary`2``, which two different variable descriptors both claimed)
and array types (`Byte[]`).

Moving the registrations to engine construction has a consequence worth pinning
beyond the ordering: a global installed by the host through `configureEngine` is
no longer overwritten by the built-in registration of the same name. The lazy
global for `Guid` is already installed when that callback runs, and
`Engine.SetValue` goes through `[[Set]]` on the global object, which reads the
current value — running the factory once and discarding the result — before
replacing the descriptor. The end state is the host value, but only the test
says so.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

* perf(javascript): register the common functions lazily

The same argument as the type globals, applied to the other bulk registration a
fresh engine pays for. `ConfigureEngineWithCommonFunctions` installs
twenty-seven functions on every engine — `getVariable`, `toJson`, `newGuid`, the
base64 helpers, the deprecated GUID pair — and each `engine.SetValue(name,
Delegate)` builds an interop function wrapper around the delegate: a JavaScript
function object, plus the signature metadata and invoker lookups Jint resolves
per delegate type. An expression such as `variables.Foo` or a comparison calls
none of them.

This was recorded in the PR as deferred, because a lazy version had to keep the
`NonEnumerable` flag `SetValue(string, Delegate)` applies — otherwise the
functions would start appearing in `Object.keys(globalThis)`, which is
observable. Jint 4.15.3's `Engine.Advanced.AddLazyGlobal` takes a `PropertyFlag`
and is the post-construction counterpart of the options-time API used for the
type globals, so the flag is passed explicitly and the port is a line per
function. The CLR delegate is now created inside the factory as well, so a
function nothing reads costs one closure rather than a closure, a delegate and a
wrapper.

The laziness is invisible, and the tests say so rather than leaving it implied.
`AddLazyGlobal` installs the property itself eagerly and defers only its value,
so `in`, `hasOwnProperty` and `Object.getOwnPropertyNames` answer immediately
without materialising anything; `Object.keys(globalThis)` still omits them; the
descriptor still reports writable, non-enumerable and configurable; two reads of
a function are the same value, which is what says the factory ran once and the
result was stored rather than recomputed per read; and a script can still
overwrite one.

Not separately measured. The measured table in the PR predates this commit and
was not re-run for it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

* refactor(javascript): let Jint expose enums as names and type its converters

`EnumToStringConverter` turned every CLR enum crossing into JavaScript into
`Enum.ToString()`. Jint 4.15 does that with `Interop.EnumConversion`, so the
converter goes away.

It is not only fewer moving parts. The converter could only see values that
crossed the interop boundary, and a constant read off a registered enum type
does not: `LogPersistenceMode.Include` came back as the underlying number while
the same value held in a workflow variable came back as `"Include"`, so
`mode === LogPersistenceMode.Include` was always false. The built-in switch
covers both directions and they now agree. Values written back to the CLR keep
accepting the member name and the number, as they did before.

That fix changes what an expression using a constant *numerically* produces, and
the hazard worth calling out is persisted state: a workflow variable holding a
number written from a constant before the upgrade no longer compares equal to
that constant after it, which reaches in-flight and resumed instances rather
than only new ones. Typed conversions hold in both directions, so activity
inputs and typed variable reads are unaffected. Recorded in the 3.8.0 changelog.

The two remaining converters register through the overload that declares the CLR
types they handle. A converter that does not declare them has to be offered
every value crossing the boundary, which costs the engine its compiled
member-read and method-invoker lanes for every wrapped .NET object; declaring
`byte[]` and `JsonElement` keeps those lanes for everything that cannot produce
one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

* perf(javascript): register only the accessors an expression names

Every evaluation registers a getter and a setter for each variable in scope, a
getter for each workflow input, and a getter for each (activity, output) pair in
the enclosing container. The last of those is the expensive one: naming those
accessors walks every node of the workflow and resolves each against the
activity registry, so the cost of setting up an engine grows with the size of
the workflow rather than the size of the expression. Almost no expression uses
any of them.

Jint reports the free identifiers of a prepared program through
`Prepared<T>.ReferencedGlobals`, which is exactly the question being asked here:
an identifier the expression never mentions cannot be read from it. The
evaluator now prepares the script before configuring the engine — the parse was
already cached, so this only reorders work — and passes the set on
`EvaluatingJavaScript`. The accessor handler registers a name only if it is in
the set, and skips the workflow walk entirely when no identifier of the
`get{Output}From{Activity}` shape appears.

The filter is sound for an expression that names an accessor the way one is
meant to be named, and not for one that builds or reaches a name at run time.
Four such forms are detectable and each turns the filter off. A direct `eval`
call is reported as `HasDirectEvalCall`. An *indirect* `eval` call and the
`Function` constructor are deliberately not flagged as direct calls — Jint
reports the identifiers `eval` and `Function` in the set instead, and says so,
because that is the signal a host is meant to act on. Missing that signal is not
theoretical: `new Function('return getMyVariable()')()` would regress from
working to a `ReferenceError`, since Function-constructed code resolves only
against the global scope, and `var e = eval; e('getMyVariable()')` would fail the
same way. The fourth is a reference to `globalThis`, which reaches a global
without naming it. All four are pinned.

What stays undetectable is reaching the global object without naming it at all —
a sloppy-mode top-level `this`, or `[].constructor.constructor(…)`. An
expression written that way loses the generated accessor but not the data:
`getVariable(name)`, `getInput(name)` and `getOutputFrom(activityId, outputName)`
are always registered and reach the same values.

Note this does not replace the regular expression in
`ConfigureEngineWithVariables`, which extracts the member names in
`variables.Foo`. Those are not free identifiers and Jint deliberately does not
report them; the set only says whether `variables` itself is referenced.

The filtering is invisible from inside a script, which also makes it unprovable
from there, so two of the tests hold on to the engine and assert on the globals
directly.

While here, the cancellation token is registered as an engine constraint.
Passing it to `EvaluateAsync` only covers the awaiting part; Jint's own remarks
say the parameter cannot preempt the synchronous evaluation loop and point at
this constraint, so the token read as more coverage than it delivered. A
cancellation constraint is amortizable, so the interpreter keeps its tight-loop
fast path, and a default token registers nothing. #7891 supersedes this with the
full constraint set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

* perf(javascript): build marshalled variables in Jint's shaped representation

`ConvertToJsObject` built the JavaScript object a workflow variable is copied
into one `DefineOwnProperty` call at a time, with an explicit descriptor. That
lands the object in Jint's per-object property dictionary, so every marshalled
variable carries its own descriptors even though sibling variables and the
repeated nested payloads of one document present the same key set.

`JsObject.CreateFromEntries` defines the same writable, enumerable and
configurable properties but builds through the shared-layout path. Both wins
land inside a single evaluation — half the descriptor allocations, since the
explicit descriptor caused a second one inside `ValidateAndApplyPropertyDescriptor`,
and one shared layout across objects presenting the same keys. Nothing carries
across evaluations: layouts are interned per engine and per-node inline caches
live in per-engine handler trees that only engage on a second evaluation on the
same engine, which a fresh-engine-per-evaluation host never reaches.

Reaching the shared layout is silent: `CreateFromEntries` falls back to the
ordinary property dictionary whenever a key or a growth guard says the layout
cannot continue, and the object behaves identically either way. A test now asks
the engine whether the object actually got one. `Engine.Advanced.HasSharedShape`,
added in 4.15.3, is the part of that answer Jint documents as a contract — the
finer-grained `GetObjectRepresentation` names an internal representation that may
be renamed or subdivided in any release — and `CreateFromEntries` is one of its
three documented success cases. The assertion is not vacuous: against the
previous property-by-property build it is false, including for the
`CreateDataProperty` variant in #7892, because that object is created through
`Intrinsics.Object.Construct` rather than built as entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

* test(javascript): run the scripting suites with Jint's host-contract verifiers on

Jint has a set of verifiers for the extension points it *trusts* — the ones it
cannot afford to re-check on a hot path, so a violation is otherwise silent.
They used to be compiled out of Release, which made "run your suite against a
Debug Jint" the only way to reach them, and Jint ships Release-only. 4.15.3
moves them behind an AppContext switch read once at type initialization, so a
host that never sets it pays nothing (the JIT folds the guards away) and a test
host can turn them on against the shipped package.

The one Elsa is subject to today is the object-converter type declaration this
PR introduced. Registering a converter with `AddObjectConverter(converter,
handledTypes)` promises the engine the converter produces values only for those
types, and in exchange the compiled interop lanes are kept for every member that
cannot produce one. Nothing links that promise to the converter's own
`TryConvert` switch: a case added there and not added to the registration is
silently skipped on exactly the members the declaration excluded, and honoured
everywhere else. `ByteArrayConverter` and `JsonElementConverter` are consistent
today; this is what would report it if they drifted.

Elsa defines no `ObjectInstance` subclass, so the rest of the verifiers have
nothing to check here yet. They are a standing guard for the day a host handler
or a satellite module adds one.

Wired as a module initializer, because the switch has to be set before the first
use of any Jint type. Duplicated across the three suites that reference
`Elsa.Expressions.JavaScript` rather than shared: `Elsa.Testing.Shared.Integration`
would be the obvious home, but it is a published package, and a module
initializer there would flip a process-wide switch for every external consumer
of it as well. A one-line test pins that the initializer ran, since Elsa
satisfies the contracts it is subject to and nothing else would notice the
checks going away.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
2026-08-17 01:44:03 +02:00
Marko Lahma 58c3c799f8
Stop registering colliding and unreachable type globals in JavaScript expressions (#7893)
* fix(javascript): stop registering colliding and unreachable type globals

`Engine.RegisterType` exposes a .NET type under `Type.Name`. That name is not
always usable, and the type registrations are contributed by several
independent handlers whose sets overlap.

* `IDictionary<string, string>` and `IDictionary<string, object>` are both named
  ``IDictionary`2``, so the two registrations claimed the same global and the
  later one silently won. Neither is reachable from a script: a backtick cannot
  appear in an identifier.
* `byte[]` is named `Byte[]`, which is likewise unreachable.
* `DateTime`, `DateTimeOffset`, `TimeSpan`, `Guid` and `LogPersistenceMode` are
  part of both the common type set and the default workflow variable descriptor
  set, so each was constructed and assigned twice for every expression
  evaluation.

`RegisterType` now skips types whose name is not usable as a JavaScript
identifier, and skips a type that is already registered under that name. Type
aliases used by the TypeScript definition endpoint are unaffected — they are
maintained by `ITypeAliasRegistry` and are independent of this registration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

* fix(javascript): leave an already-occupied global name alone

`RegisterType` skipped a name only when it already held a `TypeReference` for the
same type, so anything else under that name was replaced. That includes a global
the host installed through the per-evaluation `configureEngine` callback,
`JintOptions.ConfigureEngine` or `JintOptions.RegisterType` — all of which run
before the built-in registrations, since those are contributed by handlers of
`EvaluatingJavaScript`. Silently overwriting a host global is surprising and the
host has no way to win.

`RegisterType` now leaves any occupied name alone. That keeps the duplicate
suppression the check was written for — registering the same type twice is still
a no-op, so the overlapping handlers stop describing the same types through
reflection on every evaluation — and additionally makes the host global win. It
also agrees with #7895, where the registrations move to engine construction and
every host extension point runs after them.

Two tests pin the behaviour: a host value set under a built-in type's name
survives the built-in registrations, and `RegisterType` installs a
`TypeReference` that a second registration leaves untouched.

The remark about unusable type names is tightened while here: ``IDictionary`2``
and `Byte[]` can be reached through bracket notation if they are registered, so
the reason to skip them is that they cannot be written as identifiers, and that
every constructed generic type of the same arity claims the same global.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 01:23:31 +02:00
Marko Lahma 66b9079d3e
Bound JavaScript expression execution (#7891)
* feat(javascript): bound JavaScript expression execution

JavaScript expressions were evaluated with no execution constraints at all: no
timeout, no statement limit, no memory limit, no recursion limit, and the
ambient `CancellationToken` — already available at the call site and already
passed into `IJavaScriptEvaluator.EvaluateAsync` — was never handed to Jint.
An expression as simple as `while (true) {}` therefore occupied the calling
thread for the lifetime of the process, and cancelling the workflow did not
stop it.

This adds:

* `JintOptions.ExecutionTimeout` — wall-clock limit for a single expression,
  defaulting to 30 seconds. Deliberately generous so that existing expressions
  are unaffected; set to `null` to remove the limit.
* `JintOptions.MaxStatements`, `JintOptions.MemoryLimit` and
  `JintOptions.MaxRecursionDepth` — opt-in resource limits, off by default.
* The cancellation token is now passed to Jint, so cancelling a workflow aborts
  a script that is still running.

The security assessment documents already described a JavaScript execution
timeout as present; they now describe what is actually configurable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

* test(javascript): bound the constraint tests and cover the memory limit

Three of the execution-constraint tests removed the execution timeout entirely
and then ran `while (true) {}`, relying solely on the constraint under test to
stop them. If that constraint regressed, the test did not fail — it ran until
the CI job was killed, taking the rest of the suite with it.

Each such test now registers a generous 30 second failsafe timeout instead of
disabling the timeout. That is two orders of magnitude more than any of these
constraints needs (the slowest aborts in ~270 ms), so it cannot become a flaky
failure on a loaded machine, and `AssertAbortedByAsync` reports a failsafe trip
as exactly that rather than as an unexplained exception type mismatch.

The cancellation test also no longer races a wall-clock timer against engine
construction: the script signals the token itself through a host function, so
cancellation is guaranteed to land while the expression is running. The test
went from a 250 ms wall-clock wait to 5 ms and has no timing dependency left.

Adds the missing `MemoryLimit` test — the one configurable limit the suite did
not exercise. Doubling a string crosses the limit within a couple of dozen
statements, so it asserts `MemoryLimitExceededException` in ~40 ms and bounds
how far past the limit the process can get before the check fires.

Finally, the `ExpressionExecutionContext` is now built on the test host's
`IServiceProvider` rather than a throwaway empty one, matching every other test
in this project. An empty provider does not reflect real evaluation and can hide
failures in notification handlers that resolve services.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 01:21:19 +02:00
Marko Lahma 2e9a3ad04f
Trim per-evaluation work in the JavaScript evaluator (#7892)
* perf(javascript): trim per-evaluation work in the JavaScript evaluator

A Jint engine is built for every expression evaluation, so anything done during
setup is paid for on every evaluation. Four pieces of that work are avoidable:

* The three `IObjectConverter` implementations are stateless but were allocated
  fresh for every engine. They are now shared static instances.

* Every prepared-script cache lookup — including hits — computed a SHA-256 hash
  of the expression text, base64-encoded it and concatenated a prefix, purely to
  build the cache key. Using a dedicated key type instead keeps the entries
  distinct from other users of the shared cache while letting the expression
  itself be the key, so a hit is a dictionary lookup. Looking the entry up
  directly rather than through `GetOrCreate` also keeps the factory closure off
  the hit path.

* `ObjectConverterHelper.ConvertToJsObject` built an explicit `PropertyDescriptor`
  per property and called `DefineOwnProperty`. `CreateDataProperty` is public,
  produces exactly the same writable/enumerable/configurable descriptor, and is
  the engine's fast path for it.

* The variable write-back resolved the workflow input names — walking the whole
  activity execution context ancestor chain — before checking whether there was
  anything to write back. Only variables the expression actually referenced are
  copied into the engine, so for the common case of an expression that never
  mentions `variables.` the container is empty and all of that work is wasted.
  The input names are also now looked up through a set rather than a list.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

* test(javascript): pin the parse-failure test to the same exception every time

Calling `ThrowsAnyAsync<Exception>` twice only proved that both evaluations threw
something, which is exactly the assertion a poisoned cache would still satisfy:
had the failed preparation left a null or half-built entry behind, the second
evaluation would have failed too, just with a different exception. The test now
captures both exceptions and asserts they are the same type with the same
message, so "keeps reporting the same parse failure" is what is actually checked.

The message is stable to compare: it is `Could not prepare script: Unexpected end
of input (1:9)`, and since both evaluations run the identical script literal the
position is identical as well. No file or path detail is involved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 01:16:38 +02:00
Marko Lahma 14173a19eb
Update Jint to 4.15.3 and stop blocking the calling thread on promises (#7894)
* chore(javascript): update Jint to 4.15.3 and stop blocking on promises

`Engine.Evaluate(...).UnwrapIfPromise()` blocks the calling thread while the
engine's event loop drains, which is exactly the wrong thing to do inside an
`async` method — an expression that awaits a .NET `Task`, such as one calling
`getSecret()`, held a thread pool thread for the duration of the I/O.
`Engine.EvaluateAsync` awaits the returned promise instead, and takes the
cancellation token while it is at it.

The Jint version is moved from 4.4.2 to 4.15.3. `EvaluateAsync` arrived in
4.14.0, but the pin lands past 4.15.2 deliberately: once expressions genuinely
suspend and resume instead of draining the event loop on the calling thread,
they exercise the async suspension machinery 4.15.2 corrected — an `await` on a
right-hand side no longer stores the suspension sentinel, async generators and
`for await...of` preserve loop iteration state across a suspension, and a
suspension node is unwrapped correctly. Shipping the non-blocking change on an
earlier 4.14/4.15 would enable exactly the code paths those releases fixed.

One default changed along the way: since 4.14 `Interop.ArrayConversion` defaults
to `LiveView`, so a CLR array reaches script as a live view over the original
array rather than as a copy. That is observable — a script that sorts an array
would now reorder the workflow's own array, and the value round-trips back as
its original element type rather than as `object[]`. The evaluator therefore
pins the previous `Copy` behaviour so the upgrade is not a behavioural change;
hosts that prefer the live view can opt in through
`JintOptions.ConfigureEngineOptions`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

* test(javascript): pin the array copy lane and adopt JsString.Create

The array audit. The parent commit fixes `ArrayConversion` to `Copy`, because
4.14 changed the default to `LiveView` and the two differ in behaviour a script
can observe. The existing tests assert what a copy *produces*, which a live view
also satisfies for a value nothing mutates; asking the engine how many
conversions of each kind it performed (4.15.1's interop conversion counters)
pins the lane itself. The second assertion is the more interesting one: an
ordinary evaluation converts no CLR array at all, because Elsa converts
collection-valued variables itself in `ObjectConverterHelper` long before Jint's
array lane could see them. That makes the `ArrayConversion` setting a narrow
compatibility pin rather than something every evaluation depends on.

`JsString.Create` (public since Jint 4.15.3) is adopted in
`JsonElementConverter`, where the string case was the only one still routed
through `JsValue.FromObject` — re-entering the whole conversion pipeline, the
registered object converters and this one included, to arrive at the same call
the number and boolean cases beside it already make directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV6H9cTntzsoKiaJRBn4f

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 01:02:04 +02:00
Sipke Schoorstra 556e931662
Add JavaScript secret functions 2026-06-01 09:26:05 +02:00
Sipke Schoorstra 842cf7c162
[codex] Fix console log metadata and type resolution (#7542)
* Avoid null endpoint DTO metadata in tests

* Enforce console logs hub read permission

* Remove unused console logs hub import

* Support mapped endpoint metadata in auth tests

* Reduce console log capture throughput impact

* Address Copilot console logs review

* Refactor task scheduling to support tenant-level background work and enhance logging functionality.

* Introduce ConsoleStreamHook for stdout/stderr tee and enhance logging validation. Adjust test cases and startup warnings for distributed lock provider usage.

* Refactor console logging pipeline with capture optimization and new ConsoleLogsHost; update tests accordingly.

* Add Ansi SGR parser for console logs and associated unit tests

* Remove ANSI color renderings and parsers; integrate ConsoleLogScopeAccessor for improved logging context with workflow instance ID support.

* Address console logs code quality feedback

* Address PR review feedback

* Preserve console logs extension points

* Stabilize console logs host lifecycle

* Address final automated review comments

* Tighten console log capture shutdown

* Address console log review feedback

* Address follow-up review feedback

* Cover final review feedback

* Avoid recursive console provider initialization

* Guard console host lease shutdown

* Preserve console log scope and provider lifetime

* Correlate console log scope fallback

* Tighten console scope correlation

* Expose host services during provider construction

* Redact ANSI-normalized console lines

* Add OpenTelemetry diagnostics backend foundation

* Add OTLP HTTP ingestion parsing

* Document OpenTelemetry diagnostics setup

* Enforce OpenTelemetry hub permissions

* Remove `ConsoleCaptureTee` and related services and tests

* Add OpenTelemetry HTTP ingestion integration test

* Use pipeline contributors for console log context

* Update CShells package versions to 0.0.24-preview.132

* Add OpenTelemetry ingestion security tests

* Add OpenTelemetry API authorization tests

* Filter live console logs by workflow instance

* Add OpenTelemetry hub tests

* Add OpenTelemetry gRPC metadata hook

* Assert OpenTelemetry workflow tags survive ingestion

* Mark OpenTelemetry core build verified

* Enhance console logging with activity execution metadata and extend test coverage.

* Address console logs stream consumption comment

* Wire OpenTelemetry diagnostics into core sample

* Address Core diagnostics review feedback

* Address Core Copilot follow-up feedback

* Add OpenTelemetry metric instrument names

* Address Core Copilot provider feedback

* Address Core Copilot diagnostics follow-up

* Address Core Copilot live feed feedback

* Address Core Copilot store feedback

* Integrate OpenTelemetry for logging, tracing, and metrics in ModularServer and update launch settings and docker-compose configuration.

* Refactor to replace `ConsoleLogStream.Core` with `ConsoleLogStreaming.Core` across codebase and update `ConsoleStreamHook` installation.

* Add diagnostics OpenTelemetry backend

* Fix OpenTelemetry live hub subscription

* Fix modular OpenTelemetry exporter endpoints

* Add CShells logging configuration in appsettings.json

* Remove obsolete unit tests and helper classes

* Restore default activity exception handling

* Simplify type serialization and alias management

This commit refactors the internal type serialization and alias management system to reduce boilerplate, improve robustness, and simplify the developer experience:

-   Removed numerous explicit `ExpressionOptions` type alias registrations across various modules.
-   Updated `TypeJsonConverter` and polymorphic serialization to reliably handle types using assembly-qualified names when a short alias is not explicitly registered.
-   Streamlined `ExcludeFromHashConverter` to strictly adhere to `ExcludeFromHashAttribute` for hash calculations, removing complex `JsonIgnoreCondition` logic.
-   Eliminated several helper classes (`WorkflowJsonTypeResolver`, `WorkflowTypeValidator`, `IWorkflowTypeRegistry`, `WorkflowFactoryDictionary`, `JavaScriptExceptionTypeAliasRegistrar`, `WorkflowRuntimeTypeAliasRegistrar`) and their associated unit tests, simplifying the codebase.

Additionally, this commit introduces a comprehensive markdown document (`product-website-feature-source.md`) outlining Elsa's core features, Studio capabilities, extension ecosystem, and architectural selling points, intended as source material for the product website.

* Refine type serialization for improved robustness and alias handling

This commit further enhances the type serialization and deserialization mechanisms:

*   Centralizes type resolution and alias management through `IWellKnownTypeRegistry` and `WorkflowJsonTypeResolver`.
*   Prioritizes registered type aliases when serializing type metadata in `PolymorphicObjectConverter`, resulting in more concise JSON output.
*   Enhances deserialization in `PolymorphicObjectConverter` and `VariableMapper` to gracefully handle unknown or non-instantiable types, providing fallbacks and logging warnings.
*   Simplifies `TypeJsonConverter` by delegating complex type resolution logic to the `WorkflowJsonTypeResolver`.
*   Adds `JsonArray` to the well-known type aliases for direct recognition.

* Fix console logs packaging and workflow type resolution

* Fix console log metadata and type resolution

* Address Copilot review feedback

* Enhance type resolution, improve console log handling, and update tests

- Streamlined `WorkflowDictionaryExtensions` for better workflow registration validation.
- Refined `ConsoleLogsAuthorizationTests` with the new `SetJsonRequest` helper to improve test requests handling.
- Updated `OrderDefinition` to ignore JSON serialization for `KeySelector`.
- Enhanced `WorkflowRuntimeFeature` for improved workflow registration and type alias configuration.
- Added tests to ensure `ConsoleLogProvider` metadata filtration in various scenarios.
- Improved type serialization logic in `WorkflowJsonTypeResolver`.
- Updated README to fix references related to diagnostics.
- Optimized `ExcludeFromHashConverter` for property serialization conditions.
- Modified `TriggerIndexer` for streamlined trigger management.
- Tested payload checks in `PublishEventTests`.
- Adjusted `Endpoint` in `ConsoleLogs` for automatic JSON request handling.
- Ensured registration of workflow type aliases in `WorkflowsFeature`.

* Restore CLR workflow registration compatibility

* Align JSON island serialization fixtures

* Add Console Logs Services and Enhance Endpoint Handling

- Introduced `ActivityExecutionsEndpointTests` to validate route exposure.
- Added `ConsoleLogCaptureHostedService` for console log streaming.
- Implemented `ConsoleStreamJsonConverter` for JSON conversion of console streams.
- Developed `ElsaConsoleLogRecentBuffer` to handle recent log buffering.
- Updated `ConsoleLogsAuthorizationTests` with new test cases for stream filter mapping.
- Consolidated console log provider dependencies and registration, including recent buffering.
- Enhanced `ElsaConsoleLogProvider` to use recent buffer for filtering.
- Adjusted `Program.cs` for streamlined logging service setup.

* Enhance type resolution and test coverage; streamline console log integration

- Added `ConsoleStreamHook` for streamlined log streaming.
- Updated `WorkflowJsonTypeResolverTests` to improve type resolution and test new scenarios.
- Simplified type resolution by removing trusted assembly checks.

* Fix CI smoke and package restore failures

* Fix Docker smoke image project paths

* Fix Docker Python runtime packages

* Fix Docker CA smoke teardown

* Refresh Elsa roadmap

* Implement background processors and mediation coordination

- Added `BackgroundCommandProcessor`, `BackgroundJobProcessor`, and `BackgroundNotificationProcessor` classes for handling commands, jobs, and notifications, respectively.
- Introduced `MediatorBackgroundProcessingCoordinator` to coordinate the execution of all background processors.
- Implemented `MediatorBackgroundTask` for wrapping `MediatorBackgroundProcessingCoordinator` in `BackgroundTask`.
- Added unit tests for `MediatorBackgroundTask` to ensure proper start and stop behavior.
- Refactored `BackgroundCommandSenderHostedService` to utilize `BackgroundCommandProcessor`.
- Introduced 'elsa-roadmap-refresh' skill configuration for roadmap updates.

* Address workflow type resolution review feedback

* Address follow-up review feedback

* Restore recent console logs execute path

* Address Copilot follow-up review

* Decouple workflow JSON aliases from expressions

* Fix workflow management unit test setup

* Fix console logs recent endpoint handler shape

* Respect workflow JSON strict type aliases

* Remove unused console log contracts reference

* Address Copilot review feedback

* Address Copilot follow-up comments

* Synchronize ring buffer dropped count

* Address background processor strategy replay
2026-05-30 22:52:01 +02:00
Sipke Schoorstra cec3281a20
[codex] Harden workflow JSON type resolution (#7499)
* Harden workflow JSON type resolution

* Harden workflow type alias serialization

* Register JSON island type aliases

* Fix workflow JSON aliases for runtime types

* Register CLR workflow type aliases at startup

* Register safe workflow serialization aliases

* Use registered workflow type aliases in serializers

* Restore trusted legacy workflow JSON aliases

* Share runtime workflow type alias registration

* Address workflow JSON review follow-ups

* Address workflow JSON review follow-ups

* Address workflow JSON review edge cases

* Address workflow JSON converter review feedback

* Register workflow JSON types for HTTP and JavaScript failures

* Address secure type serialization review comments

* Address deserialization review feedback

* Address workflow serialization review comments

* Address workflow type review feedback

* Tighten workflow type hardening fixes

* Avoid workflow alias string type resolution

* Address workflow type alias review feedback

* Stabilize publish event payload assertion

* Stabilize bulk dispatch component test

* Make workflow dictionary aliases idempotent

* Declare workflow runtime feature dependency

* Assert trigger payload alias serialization

* Import workflow helper contracts

* Avoid duplicate CLR workflow materialization

* Normalize workflow factory aliases
2026-05-22 15:25:49 +02:00
Sipke Schoorstra a80490101a
Refactor flowchart activity execution logic to improve modularity and add enhanced support for FlowJoin activity types. 2025-12-10 21:34:00 +01:00
Sipke Schoorstra 0ef0135303
Merge remote-tracking branch 'origin/patch/3.5.3' into develop/3.6.0 2025-12-10 20:48:50 +01:00
Sipke Schoorstra 2f9eac110e
Upgrade projects to target .NET 10, add conditional System.Linq.Async dependencies for compatibility with earlier frameworks, and update project files for consistency across the solution. (#7062)
* Upgrade projects to target .NET 10, add conditional `System.Linq.Async` dependencies for compatibility with earlier frameworks, and update project files for consistency across the solution.

* Suppress null comparison warning in `WorkflowDefinitionStore` and remove xUnit references from performance test project.

* Refactor performance test projects to remove xUnit references and update MSBuild properties for BenchmarkDotNet.
2025-11-21 20:55:30 +01:00
Sipke Schoorstra d84e97945c
Add integration test for newGuid() in JavaScript evaluator.
Introduces a new unit test in `Elsa.JavaScript.IntegrationTests` to verify that the `newGuid()` function in the JavaScript evaluator correctly returns a `Guid` type.
2025-11-12 17:09:13 +01:00
Sipke Schoorstra 8747151330
Add code coverage configuration and adjust test projects (#7049)
* Add code coverage configuration and adjust test projects

- Introduced `Include` and `Threshold` properties across test project files for improved code coverage tracking.
- Added `coverlet.collector` as a dependency for coverage data collection.
- Removed unused `global using` directives and redundant imports for cleaner test codebases.

* Update GitHub Actions workflows for pull request triggers

- Adjusted `pr.yml` to include `patch/*` and `develop/*` branches.
- Removed redundant pull request triggers in `packages.yml` for cleaner configuration.

* Expand pull request triggers in GitHub Actions

- Renamed `PR` workflow to `pr` for consistency.
- Included `patch/*` and `develop/*` branches in `pr.yml` and `Build.CI.GitHubActions.cs`.

* Remove pack target from pull request workflows

- Updated `pr.yml` to exclude the pack step.
- Adjusted `Build.CI.GitHubActions.cs` to reflect the removal of the pack target.

* Remove `Elsa.Workflows.Api` from integration test project references

- Updated `Elsa.Workflows.IntegrationTests.csproj` to exclude `Elsa.Workflows.Api` from the `Include` list and project references for cleanup and simplification.
2025-11-12 13:59:36 +01:00
Sipke Schoorstra b32a067d03
Add DispatchWorkflow tests with new workflow definitions (#7035)
* Add DispatchWorkflow tests with new workflow definitions

- Introduced multiple workflow definitions with varied scenarios including input handling, correlation IDs, and fault handling.
- Enhanced `DispatchWorkflowsTests` with comprehensive test cases to validate `DispatchWorkflow` behavior under different configurations.
- Updated existing workflows and tests for improved structure, readability, and accuracy.
- Refactored and renamed related workflows for consistency across test suites.

* Update test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/DispatchWorkflows/DispatchWorkflowsTests.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Refactor DispatchWorkflowsTests for readability and maintainability

- Replaced hardcoded constants with named variables for improved clarity.
- Enhanced assertions using utility methods like `Assert.Single` for cleaner code.
- Updated WriteLine activity tests to handle null values reliably.
- Introduced timeout handling for child workflow execution.

* Update GUID length validation in JintJavaScriptFunctionBehaviorTests

- Adjusted `shortGuid` length assertion to accommodate a range of 19-22 characters instead of 20-22.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-06 20:47:20 +01:00
Sipke Schoorstra d1f3ca7e41
Add integration tests for JavaScript function availability and behavior validation
- Introduce `JintJavaScriptEvaluatorTests` to ensure all JavaScript custom functions are available and callable.
- Add `JintJavaScriptFunctionBehaviorTests` to validate execution and behavior of JavaScript functions.
- Extend `WorkflowTestFixture` with `CreateExpressionExecutionContextAsync` for testing JavaScript expressions.
- Update test guidelines with examples for testing JavaScript functions and evaluating expressions.
2025-10-21 21:31:47 +02:00
Sipke Schoorstra ad0dfad77e
Enhance WorkflowTestFixture and RunJavaScript tests with additional examples and helper methods
- Add integration test cases for validating script execution, outcomes, workflow variables, and fault handling.
- Introduce helper methods in `WorkflowTestFixture` for outcome retrieval, activity status, and output assertions.
- Extend test guidelines with usage examples for new `WorkflowTestFixture` capabilities.
2025-10-21 20:36:24 +02:00
Sipke Schoorstra efe849d0bc
Add integration tests for RunJavaScript activity and introduce WorkflowTestFixture
- Implement tests to validate execution of valid and invalid scripts, outcome settings, workflow variable access, and complex script handling.
- Add `WorkflowTestFixture` to streamline integration testing setup and execution.
2025-10-21 20:02:27 +02:00
Sipke Schoorstra b1d9d04150
Parse VariableTestValues more robustly, leveraging ExpandoObject and type conversion logic. (#6883)
* Parse `VariableTestValues` more robustly, leveraging `ExpandoObject` and type conversion logic.

* Clean up unused imports in `JavaScriptAndNetTypeTest`.
2025-08-31 08:50:07 +02:00
Sipke Schoorstra 2a10738d94
Merge remote-tracking branch 'origin/patch/3.5.1' into develop/3.6.0 2025-08-20 14:12:25 +02:00
Sipke Schoorstra 2175a3470a
Refactors JavaScript type handling (#6858)
* Exclude blacklisted types (`string`, `object`, `Array`, `DateTime`) from workflow variable registration logic.

* Add integration tests for JavaScript evaluation and update type blacklist in `ConfigureEngineWithVariableTypes`

* Disable central package transitive pinning and update Elsa Studio version to `3.5.0`.

* Update Microsoft version to 9.0.8 in Directory.Packages.props

* Enable central package transitive pinning in `Directory.Packages.props`.
2025-08-20 14:10:16 +02:00
Matt 10348c5ea3 Update all dependencies to new projects. 2025-05-21 00:20:13 +01:00
Sipke Schoorstra 923e9d335d
Refactor variable initialization for clarity and consistency
Updated variable constructors across the codebase to use explicit names and initial values where applicable. Deprecated old constructor overloads and added new methods and overloads for better flexibility and readability. Minor cleanup includes replacing `default` keywords with `null` and streamlining code syntax.
2025-03-13 21:05:28 +01:00
Sipke Schoorstra cc694bf15b Use var for local variables in test cases
Updated all instances of explicitly typed `string` and `JsonElement` to `var` in `JsonElementConverterTests.cs` to improve code readability and maintain consistency with modern C# coding practices. This change does not affect functionality but aligns with better style conventions.
2025-01-14 23:19:51 +01:00
Sipke Schoorstra efd114944c Refactor and enhance JavaScript and object conversions.
Replaced InputProxy with alternative implementations, adding flexibility to handle inputs. Introduced a JsonElementConverter to deepen JavaScript and JSON element integration. Enhanced testing and object conversion logic, improving type handling and support for complex JSON scenarios.
2025-01-14 23:16:29 +01:00
Robin Sue 4d6b7a17fb Add .NET 9.0 target 2024-12-10 21:06:42 +01:00
FunShow 5ac63f1485
fix JavaScript BigInt mapping to BigInteger serialization incorrect (#6164)
* fix: fix JavaScript BigInt mapping to BigInteger serialization incorrect

* test: add test for BigIntegerJsonConverter

* test: add test for BigIntegerJsonConverter

---------

Co-authored-by: funshow.liu <funshow.liu@didatravel.com>
2024-12-03 15:07:40 +01:00
Sipke Schoorstra 77a71afc7a
Refactor Workflow Runtimes (#5444)
* Add caching to workflow runtime and workflow management stores

The update introduces caching to workflow runtime and workflow management stores to enhance performance. This is achieved by adding decorators for several stores, which cache records to reduce database fetches. Additionally, a signaler for change tokens allows for cache invalidation when changes occur. The MemoryCache feature has also been updated to include Scrutor for decoration and the caching duration can be configured through the new CachingOptions class.

* Refactor WorkflowsMiddleware for HTTP Endpoint bookmarks and triggers

The WorkflowsMiddleware has been extensively refactored to handle HTTP Endpoint bookmarks and triggers. This involves breaking down the InvokeAsync method by extracting parts of its functionality into separate helper methods such as FindTriggersAsync and FindBookmarksAsync. Moreover, Assist with authorization checks, workflow execution within request timeout, and handling of workflow faults has been improved to be more efficient and clearly segmented.

* Update HTTP endpoint authorization to use Workflow context

The authorization process in the AuthenticationBasedHttpEndpointAuthorizationHandler class has been updated to use the Workflow context instead of the WorkflowInstanceId string. The AuthorizeHttpEndpointContext model has been correspondingly changed to include a Workflow property, thereby strengthening the link between authorization and specific workflows.

* Add FindAsync methods to trigger and bookmark stores

The code adjustments add new FindAsync methods to the trigger and bookmark store contracts as well as all their concrete implementations (MongoDb, Memory and EFCore). These methods support fetching the first record matching a given filter. The adjustments also include minor syntax improvements and the addition of [UsedImplicitly] attributes where needed.

* Refactor WorkflowsMiddleware for improved workflow handling

The code was refactored to simplify the flow of handling workflows in the WorkflowsMiddleware class. Specifically, the methods to start and resume a workflow have been extracted to improve code readability. Further, handleErrorMiddlewares was also updated to better manage instances where no valid workflows or base paths are found.

* Add caching functionality to WorkflowsMiddleware

Added IMemoryCache usage in the WorkflowsMiddleware to cache lookup results for workflows and their associated triggers. This will reduce the number of database operations required when searching for workflows, thus improving performance. The cache is maintained for one minute before it is refreshed.

* Implement dynamic cache duration for workflows

The code has been updated to have a dynamic cache duration for the workflows instead of a hardcoded one minute. By using the CachingOptions service, the cache duration can now be set in the configuration making it more flexible and adaptable to different performance needs.

* Add HttpWorkflowsCacheManager for caching HTTP workflows

This commit includes the implementation of IHttpWorkflowsCacheManager for caching of HTTP workflows. New handlers have been added to invalidate cache on workflow updates. Additionally, WorkflowsMiddleware has been renamed to HttpWorkflowsMiddleware.

* Refactor workflow trigger handling and caching

The refactoring includes deletion of `IndexWorkflowTriggersHandler.cs` and creation of `IndexTriggers.cs` thus revising the workflow trigger indexing approach. Also, revamped the `ITriggerIndexer` interface which now handles deletion of triggers with specific workflow and filter. Furthermore, the caching mechanism in `HttpWorkflowsCacheManager.cs` is modified to handle eviction of workflow definitions and triggers separately boosting its efficiency.

* Add summary to IndexedWorkflowTriggers

A summary has been added to the 'IndexedWorkflowTriggers' class, providing a brief description. This description outlines that it represents a collection of indexed workflow triggers, promoting clearer understanding for future reference.

* Refactor memory caching feature into separate module

This commit separates the memory caching feature from the Elsa.Common module into a distinct Elsa.Caching module. This includes moving and renaming related files, such as the MemoryCacheFeature class and associated dependencies. The references in other modules and in the main solution file have been updated accordingly to include the new Elsa.Caching module.

* Add distributed caching and update async methods

Introduced a distributed caching feature with extensible change token signal publishing. Updated various cache-related methods to be asynchronous for improved performance and responsiveness. Also updated some workflow identity references for clarity.

* Add distributed caching with MassTransit support

This addition includes the implementation of a distributed caching system with MassTransit transport. The changes introduce necessary interfaces and services, new distributed caching feature along with the support for MassTransit as a transport option. Moreover, the instance management feature has been renamed to clustering feature for better clarity.

* Refactor queue naming and scope of MassTransitChangeTokenSignalPublisher

Queue name construction is adjusted in the RabbitMqServiceBusFeature and AzureServiceBusFeature modules for better organization and readability. MassTransitChangeTokenSignalPublisher is now a singleton service, ensuring the signal publisher can be shared across the application, increasing efficiency and performance. Also, introduced use of DistributedCacheFeature in MassTransitDistributedCacheFeature module for better modularization.

* Add caching capabilities to workflow definition service

This commit introduces caching to the workflow definition service, improving the performance for retrieving workflow definitions. 4 new classes have been created (`CachingWorkflowDefinitionService`, `EvictWorkflowDefinitionServiceCache`, `WorkflowDefinitionCacheManager`, and `IWorkflowDefinitionCacheManager`), and several existing classes have been updated to support caching. The caching also includes invalidation mechanisms, ensuring data consistency.

* Refactor caching mechanism in workflow definition

In the workflow definition module, the explicit caching functionality related to workflow definition versioning has been removed in favor of a more streamlined approach. Additionally, the manner in which services are registered has been altered. As a result, the caching now directly involves the overall workflow definition rather than individual versions, simplifying the caching logic and potentially improving the performance.

* Update MassTransitBroker and enable RealTimeWorkflows and SignalRHubs

The MassTransitBroker has been updated to Memory from RabbitMq. In addition, the RealTimeWorkflows and UseWorkflowsSignalRHubs features are now enabled in the code. This change will impact how the service communicates and processes real-time requests for workflow operations.

* Reformat variable types in HttpFeature

The reformatting involves a list of variable types in the HttpFeature module. Each type now appears on a new line for improved readability, making the code easier to maintain and review.

* Update HTTP workflows cache invalidation handler XML comment

* Remove unnecessary using directives

Unnecessary using directives were deleted across several files in the Elsa.Http module. This simplifies the code and will possibly improve execution speed. Specific deletions include those for Encoding, Unicode, Extensions, Collections.Generic, Linq, Text, and Tasks namespaces.

* Refactor HttpWorkflowsMiddleware constructor

This commit simplifies the HttpWorkflowsMiddleware class constructor. It removes the intermediary variables `_next` and `_options` and directly uses the passed arguments in the constructor. Now, the `next` and `options` parameters are used directly throughout the middleware.

* Simplify workflow retrieval in HttpWorkflowsMiddleware

This refactoring replaces the use of FindWorkflowDefinitionAsync and MaterializeWorkflowAsync with a single method, FindWorkflowAsync. This simplifies the middleware code and likely improves performance by reducing the number of database queries or service calls required to retrieve a workflow.

* Refactor workflow retrieval in HttpBookmarkProcessor

Simplified the workflow retrieval process in HttpBookmarkProcessor.cs. Replaced FindWorkflowDefinitionAsync and MaterializeWorkflowAsync methods with a single FindWorkflowAsync call. This reduces the complexity and improves efficiency in retrieving workflow.

* Optimize FindWorkflowAsync method in HttpWorkflowsCacheManager

Removed redundant lines of code to simplify workflow search functionality. This change simplified the FindWorkflowAsync method by directly calling the FindWorkflowAsync function in the workflowDefinitionService, thus increasing code readability and efficiency.

* Refactor Endpoint.cs for workflow retrieval

The method for obtaining a workflow in the Endpoint.cs script has been refactored and streamlined. The 'GetWorkflowDefinition' method is replaced by the 'GetWorkflowAsync' method which directly retrieves the workflow, without the intermediate step of materializing the workflow definition. This shortens the code and simplifies the process.

* Refactor InputFunctionsDefinitionProvider constructor

The constructor for InputFunctionsDefinitionProvider has been simplified by removing unnecessary private fields. Services are now directly used in the method instead of being stored in fields. This improves readability and reduces complexity in the class structure.

* Refactor WorkflowInstance with improved state handling

Simplified the methods for handling workflow and workflow state in the WorkflowInstance class. The refactoring also included some code clean-ups and variable renaming. The new implementation provides better readability and maintainability of the code by reducing unnecessary lines and improving structuring of objects and responses.

* Remove unused IBookmarkManager and update workflow functions

IBookmarkManager from ProtoActorWorkflowRuntime.cs file is removed due to its redundant status. Additionally, the "FindAsync" method has been updated to use a cancellation token. Also, annotations were added to the "ExportWorkflowStateAsync" and "ImportWorkflowStateAsync" methods to flag calls to functions that require unreferenced code.

* Remove unused ReSharper directive

Unused ReSharper directive in the file IndexTriggers.cs was identified and therefore removed. This change makes the code cleaner and easier to read.

* Update activity invocation in workflow runtime

Updated the DefaultBackgroundActivityInvoker service in the Elsa.Workflows.Runtime module to annotate the ExecuteAsync method with "RequiresUnreferencedCode" attribute. This change is made considering the potential code trimming issue. Additionally, simplified the process of fetching workflow by directly using FindWorkflowAsync method instead of FindWorkflowDefinitionAsync and MaterializeWorkflowAsync methods.

* Refactor code to simplify workflow definition loading

The code for finding and materializing workflow definitions has been simplified. Instead of loading the definition and materializing it into a workflow in separate steps, a new method called FindWorkflowAsync has been introduced to perform both actions at once. This reduces redundancy and makes the code more readable.

* Refactor WorkflowHostFactory to streamline workflow creation

This commit simplifies the workflow creation process in WorkflowHostFactory. It removes redundant code and extraneous methods, specifically the overloaded CreateAsync method which used WorkflowDefinition. Now, it directly finds and uses the Workflow instance, thereby simplifying the code base and improving maintainability.

* Refactor workflow retrieval in WorkflowInstance.cs

Changed the way workflow instances are retrieved from the WorkflowDefinitionService. Instead of obtaining the workflow definition and then materializing the workflow from it, the workflow is directly retrieved using the FindWorkflowAsync function. This simplifies the code and avoids unnecessary null-checks.

* Remove unnecessary whitespace in WorkflowInstance.cs

An extraneous whitespace character was identified and removed in the WorkflowInstance.cs file. This change contributes towards maintaining clean and readable code in the Elsa.ProtoActor module.

* Remove unnecessary comment in ProtoActorWorkflowRuntime

The unnecessary comment ("Load the workflow definition.") in the method TryStartWorkflowAsync of the ProtoActorWorkflowRuntime.cs file was removed. This is part of an ongoing effort to keep the codebase clean and readable.

* Update workflow management features and handlers

Added explicit notification handlers for DeleteWorkflowInstances and RefreshActivityRegistry in WorkflowManagementFeature.cs. Also, renamed RefreshActivityRegistryHandler.cs to RefreshActivityRegistry.cs for better clarity.

* Add multiple log record support to workflow execution log stores

The major change of this commit is the addition of methods to add multiple log records in the WorkflowExecutionLogStore, across different storage modules such as EntityFramework, MongoDB, Dapper, Elasticsearch and Memory. This ensures consistency and uniform behavior across different storage types. Furthermore, some reformatting and tidying up of the code were undertaken to maintain readability and clarity.

* Remove redundant workflow definition check

The workflow definition existence check and related service retrieval were removed from HttpWorkflowsMiddleware.cs. It was determined that this check was unnecessary as the workflow definition's existence is guaranteed at this point in the process, reducing redundancy in the code.

* Improve cancellation token usage in workflow execution

This commit refines the usage of cancellation tokens during the execution of workflows in Elsa.Server and HttpWorkflowsMiddleware. Previously, a cancellation token pair was created before ExecuteWithinTimeoutAsync was called, which limited duration control solely to that method. Now, cancellation tokens are included within ExecuteWithinTimeoutAsync method. This allows the method to observe any cancellation initiated by outer scopes, enhancing control over the timeout of operations.

* Add PersistStateAsync method to WorkflowHost

A new PersistStateAsync method has been added to the WorkflowHost, which enables the host to directly persist its own state. The method has been integrated into the DefaultWorkflowRuntime and HttpWorkflowsMiddleware. This update eliminates the need to continuously get instances of IWorkflowInstanceManager to save state, which improves efficiency and code readability.

* Refactor DefaultAlterationRunner service

This update simplifies the DefaultAlterationRunner service, reducing the number of code lines and removing unnecessary references. The workflow materialization step has been merged with the find workflow step, and unused namespaces have been dropped.

* Refine wording in IWorkflowHost interface documentation

The documentation for the 'CanStartWorkflowAsync' method in the IWorkflowHost interface has been cleaned up. The superfluous "or not" verbiage has been removed, making it easier to understand the method's function.

* Remove CancellationTokens struct and simplify cancellation handling

Removed the CancellationTokens struct and all its references across the code base. Simplified cancellation handling by using standard CancellationToken only. Also cleaned up redundant usages and unnecessary namespaces across various modules. This simplification better aligns with standard .NET conventions and reduces the code complexity.

* Implement ActivityHandle for better activity identification

The ActivityHandle class has been introduced to consolidate various activity identification parameters such as ActivityId, ActivityNodeId, ActivityInstanceId, and ActivityHash. This makes it easier to track and manage activities by reducing the number of parameters needed for identification. Adoption of ActivityHandle has been implemented across the codebase.

* Remove AzureContainerApps related code

This commit includes the removal of all the AzureContainerApps associated code from the ProtoActor Cluster. The deletion includes multiple files which had housed the AzureContainerApps cluster provider and all its supporting services, util functions, options, contracts, and models. This move might be towards refactoring the structure or removal of unwanted dependencies.

* Add distributed execution runtime and client

Removed some unused classes and created a distributed execution runtime using distributed locking and persistence. Introduced an interface for workflow clients and implemented two versions, a local one and one using `Proto.Actor`. Made some changes in other modules to add the necessary interfaces and methods. Also, added `DistributedLockingRuntime` module to implement distributed execution.

* Remove WorkflowClient.cs from Elsa.Workflows.Runtime

The WorkflowClient.cs file was removed from the Elsa.Workflows.Runtime project. It held placeholder methods that had not yet been implemented, making it unnecessary in the current codebase.

* Add ProtoActor implementation for workflow execution

Added ProtoActor implementation for executing workflow instances. This includes ProtoBuf message definitions, grain interfaces and implementations, and various ProtoActor services. Extended WorkflowHost and related components to provide more execution details in order to better support distributed processing via ProtoActor.

* Refactor workflow parameters to workflow requests

The refactor includes renaming old 'WorkflowParams' classes to 'WorkflowRequest' to better represent their usage. The changes have been made across all the involved modules ensuring that the project maintains consistency. New properties, methods, and class names were updated accordingly.

* Add ProtoActor implementation for data mappers

This update adds the ProtoActor implementation for data mappers and updates the DI configuration accordingly. It also updates the client interfaces for a more streamlined usage, and refactors the WorkflowHost to adapt to these changes. All changes were implemented in accordance with the new bookmark information model.

* Add functionality to create a new workflow instance

This commit introduces the capability to create a new workflow instance in the Elsa Workflow Runtime by enhancing existing workflow classes and creating the WorkflowClientFactoryExtensions class, in addition to adding the "IsNewInstance" parameter to multiple workflows and requests. It provides more flexibility in managing workflow instances and aids in building workflow processes that require instantiation of a new workflow.

* Remove Elsa.Runtimes.DistributedLockingRuntime module

This commit deletes the Elsa.Runtimes.DistributedLockingRuntime module from the project. Changes include removed code files related to features, services and commands under this module. The Elsa.sln file has been updated to reflect these changes, excluding the removed module from the solution.

* Add dynamic client type to WorkflowClientFactory

The WorkflowClientFactory now accepts a client Type parameter for dynamic client creation. This enables the factory to create different subclasses of IWorkflowClient based on the provided Type. The CreateClient function is updated in the WorkflowClientFactoryExtensions and IWorkflowClientFactory interface, and applied in HttpWorkflowsMiddleware.

* Implement Proto.Actor support in Elsa

A comprehensive change that introduces support for Proto.Actor clustering to Elsa. It includes a redesign of the workflow client invocation model, transitioning the methods from synchronous to asynchronous. Also, modification to the Proto.Actor-based 'WorkflowGrain' was made to handle state recovery and execution processing. The structural enhancements improve scalability and performance capabilities.

* Refactor null-checks in SaveSnapshotAsync method

Simplified the null-checking in the method SaveSnapshotAsync within WorkflowGrain.cs. The check on _workflowHost and workflowState has been shortened using conditional access operator, improving the code readability.

* Refactor code and update packages

The codebase has undergone a major refactoring to improve code readability and consistency, with non-essential methods being removed and variable names being optimized for clarity. Package references for Proto.Actor and related packages have been also updated to the latest versions.

* Add Proto.Cluster.AzureContainerApps package to Directory.Packages.props

The Proto.Cluster.AzureContainerApps package with version 1.6.0 has been included in the Directory.Packages.props file. This addition extends the range of Proto.Cluster packages used in the project.

* Remove redundant Proto.Actor implementation files

This commit removes several redundant files related to the Proto.Actor implementation. These files were unnecessary and were cluttering up the codebase. With this removal, the project has become leaner and easier to maintain. It also eliminates potential confusion for future developers working on this project.

* Add WorkflowMatcher and replace BookmarkHasher with StimulusHasher

This commit introduces a new class, WorkflowMatcher, which represents a contract for finding triggers and bookmarks associated with workflow activities. It also renames and replaces all instances of BookmarkHasher with StimulusHasher to reflect a more accurate function relating to stimulus rather than bookmarks. Other necessary changes were made to ensure consistency with these updates across different classes. It's important to note that WorkflowInbox interface is now marked as obsolete.

* Incremental work on stimuli refactoring

* Refactor codebase to support new IWorkflowInvoker and invoke workflow logic

Multiple files updated to introduce a `IWorkflowInvoker` interface, implementation and supporting classes. This simplified how workflows are instantiated and invoked. Consequently, necessary adjustments made across multiple entities and endpoints to account for the updated invocation procedure. Old logic related to counting running workflows removed. Introduced stimulus concept while deprecating non-compliant classes and methods.

* bumped versions to fix dependency vulnerabilities (#5256)

* Update patch version in GitHub workflows

The version number used in the branch checking step of the GitHub workflows has been updated. Instead of scanning for the branch containing the patch version 3.1.2, it now scans for the branch that contains version 3.1.3. This change is aligned with the updated product version.

* Update git branch grep pattern in workflow file

The git grep pattern has been corrected to properly identify tagged versions in the GitHub Actions workflow. The correction ensures that the workflow script fetches the right branches as per the release tag instead of patch.

* Update grep command in packages workflow

The grep command used in the 'packages.yml' GitHub workflow was previously looking for the exact 'refs/tags/3.1.3' string. This commit simplifies the command by making it only look for '3.1.3'. This adjustment will streamline the process and potentially prevent issues with branch recognition.

* Update package versions and refactor code for Elasticsearch and JavaScript modules

Updated versions of numerous packages in the Directory.Packages.props file to their latest stable releases. This includes updates to Elasticsearch, JavaScript, and MongoDB packages among others. Additionally, refactored parts of the code in the WorkflowInstanceConfiguration and JintJavaScriptEvaluator within the Elasticsearch and JavaScript modules, respectively, to improve index management and script preparation. The WorkflowInstanceStore also saw a minor adjustment.

* Refactor workflow management with workflow definition handles

The existing workflow management has been significantly refactored, introducing the concept of "Workflow Definition Handles". These handles allow for consistent management whether we're dealing with a specific workflow definition, a version of a definition, or more flexible version constraints. This refactor also adjusts how workflow instances are created, now using a more intuitive and detailed "WorkflowInstanceOptions" approach.

* Add ResumeBookmarkResult and update related methods

Implemented a ResumeBookmarkResult class to handle bookmark resumption results. Methods related to resuming bookmarks have been refactored to return this new class, providing more information such as bookmarks' matched state. Also, some methods were optimized to break the loop early if no bookmarks were found, improving code efficiency.

* Update workflow definition, execution and correlation

This commit focuses on enhancements and adjustments to workflow definition and execution. Notable changes include the addition of ExecuteResponse model and new test workflow scenarios. Refactoring has been performed to improve readability and efficiency in various components. It also includes an important fix for the correct application of WorkflowDefinition filters, primarily using both DefinitionId and DefinitionVersionId for more accurate results.

* Refactor runtime codebase for better structure and workflow control

This commit involves changes to functionally reorganize the runtime codebase for improved structure. It also allows for better handling of workflows, particularly through the addition of original bookmarks in the workflow execution context. Removed unnecessary dependencies and ensured more efficient management of bookmarks in the workflow running process. Several method and class names were also updated to better reflect their purpose.

* Refactor WorkflowInvoker and remove 'OriginalBookmarks'

Optimized the constructor of 'WorkflowInvoker' by using 'IServiceScopeFactory' to get instances of required services. Removed the 'OriginalBookmarks' property from 'WorkflowStateExtractor' and 'WorkflowState', a subsequent change included in 'WorkflowGraphBuilder' as well. Reorganized the namespaces in 'Elsa.Workflows.ComponentTests' project. Added 'UseCache' in WorkflowServer configurations.

* Removed RunWorkflowParams class

This update deletes the RunWorkflowParams class within the Runtime Requests of the Elsa.Workflows module. The class was no longer needed, hence the elimination and cleanup in the codebase.

* Update RunWorkflowParamsMapper to handle null or empty fields

This commit modifies the RunWorkflowParamsMapper in the Elsa.ProtoActor module. It primarily treats the BookmarkId and TriggerActivityId fields to return null if they are empty, boosting the application's robustness against potential null or empty field issues.

* Refactor workflow handling and improve null checks

In this update, the handling of workflows was refactored to improve efficiency. The 'RunAsync' method now correctly uses 'WorkflowGraph' as a parameter, instead of 'Workflow'. Additionally, null checks for 'bookmarkId' and 'activityHandle.ActivityInstanceId' have been improved to avoid null and empty strings. Finally, when '_workflowInstanceId' is null in the 'WorkflowGrain' class, it is now properly initialized by parsing the cluster identity.

* Enable ProtoActor in Elsa.Server.Web

This commit turns on the use of ProtoActor within the Elsa.Server.Web bundle. This switch may affect the system's behavior and performance.

* Added new workflow scheduling and management features

Implemented new features for creating, running, and scheduling workflow instances. The implementation added new files for handling workflow runtime and scheduling features, including creating and running a workflow instance request, a mapper for the request, and handler services. Modified files include updating method calls according to the new requests, updating workflow definitions, and adjustment to method arguments in Hangfire job class.

* Handle null or empty workflow instance IDs and correlation IDs

This commit introduces null checks for workflow instance IDs and correlation IDs in the workflow infrastructure. Previously, the code assumed that the IDs were provided. It now gracefully handles cases where they might be null or empty, preventing possible null reference exceptions and ensuring more robust workflow execution.

* Update mapping details in ResumeWorkflowJob

Removed unnecessary using statement for Elsa.Workflows.Runtime.Requests in ResumeWorkflowJob.cs. Updated references from DispatchWorkflowInstanceRequest to ScheduleExistingWorkflowInstanceRequest for retrieving ActivityHandle and WorkflowInstanceId.

* Refactor AzureServiceBus module and integrate into web project

In this commit, changes were made to the AzureServiceBus module to use Topic definitions for subscriptions. The Subscriptions property in the AzureServiceBusOptions and the Topic property in the SubscriptionDefinition class are marked as obsolete and suggestions to use TopicDefinition.Subscriptions instead have been added. The AzureServiceBus module was also integrated into the web project and configured to use options from the appsettings.json.

* Refactor code to use async scopes and improve service dependencies

Refactored code to use async scopes for improved task management. Also organized service dependencies better by moving service fetching inside methods where they are needed and propagating necessary dependencies through method parameters for cleaner code.

* Add Azure Service Bus workflow component tests

This commit introduces a set of workflow component tests for Azure Service Bus integration. These tests encompass scenarios like message receiving, sending messages with correlation IDS, and sending single messages. In addition, 'SignalResetEvent' test helper was removed, a new test helper 'TriggerSignal' was added, and a Mock ServiceBusClient and ServiceBusAdministrationClient were added to the WorkflowServer fixture. Lastly, the NSubstitute package was added to the test project's dependencies.

* Add support for deferred tasks in workflow execution context

Added support for deferred tasks in the workflow execution context. This implementation allows tasks to be deferred and executed right after persistence of bookmarks in the workflow. A new middleware, ExecuteDeferredActivityTasks, is introduced to handle the execution of these deferred tasks.

* Refactor TriggerSignal and SendMessage activity execution

Refactored the execution of TriggerSignal and SendMessage activities by using context.DeferTask to ensure the activities run asynchronously. Also, made code format modifications and simplifications such as handling ApplicationProperties better in the SendMessage activity, and other minor changes.

* Update workflow ID generation method

The workflow ID generation method has been updated in the WorkflowBuilder. Previously, it was always generated by _identityGenerator. Now, it only gets generated if the definitionId or Id is null or empty, otherwise it uses the existing value. This change brings the ID generation practice in line with how we handle definitionId.

* Add support for service bus testing in workflow tests

Two new helper classes, DictionaryExtensions and MockServiceBusProcessor, have been added to support mocking Azure service bus in workflow component tests. Also, the tests have been updated to use SignalManager to ensure proper order of execution. The WorkflowServer test fixture has been extensively refactored to create mock instances of service bus senders and processors. Furthermore, some configurations have been commented out and new configurations related to MemoryTriggerStore and MemoryBookmarkStore have been added.

* Enhanced workflow correlation and caching in Elsa Workflows

This update improves Elsa Workflows by enabling caching and enhancing correlation in Correlate.cs. It expands functionality by adding new methods that accept various input types and provide more options for activities correlation. Correlation improvements also extend to AzureServiceBusTests, which were updated to test workflow instances by correlation ID. Furthermore, the test workflow received a name change and new correlation mechanics based on Azure messaging.

* Renamed method argument from 'payload' to 'stimulus'

The method argument 'payload' in various functions across 'MessageReceived.cs' and 'ActivityExecutionContext.cs' files has been renamed to 'stimulus'. This change was made to improve code readability and understanding by using a more context-specific term.

* Refactor Workflow APIs and enhance logging

Refactored Workflow APIs by removing the TriggerActivityId from StimulusMetadata and introducing Direct Triggers. Refactored Reenter method in WorkflowGrain to be more concise and straightforward. Enhanced logging by adding additional logging in ActivityExecutionPipeline and LogLevel in appsettings. Also, updated ProtoActorFeature for better log level management.

* Refactor AzureServiceBusTests and add workflow completion signal

The AzureServiceBusTests class is refactored to separate and encapsulate concerns. SignalManager and WorkflowEvents are now class-level variables. Also, a signal to indicate the completion of a workflow is added. This allows the test to wait for workflow completion in the sequence of its operations. Additionally, the workflow definition ID in MessageReceivedTriggerWorkflow is now static and fixed, rather than dynamically derived from the class name.

* Refactor methods to streamline workflow creation and execution

The changes primarily consolidate the process of creating and running a workflow instance into a single operation. Specifically, the 'CreateAndRunWorkflowInstanceRequest' class is utilized in multiple modules to simplify and streamline the workflow creation process. Also, several redundant and inefficient methods were removed in the 'WorkflowGrain' module, and the remaining methods were updated to return the required response directly, resulting in cleaner, more efficient code.

* Refactor asynchronous serialization to synchronous

Simplified serialization by converting all asynchronous tasks in the workflow state serializer to synchronous ones. This change affects Elsa's Core, Dapper, EntityFrameworkCore, Management, and ProtoActor modules, as well as the Workflow State Serializer - switching all async workflow state serialization methods to their synchronous equivalents.

* Removed Elsa.ServiceBus.IntegrationTests project

The Elsa.ServiceBus.IntegrationTests project and all related files and references were removed from the solution. This update affects the main application and several workflow files, scenarios, and helper methods.

* Refactor WorkflowGrain and update ProtoActor timeouts

Renamed the Method OnStopped to async and replaced Context.Stop with Context.Poison in the Method Stop within the WorkflowGrain.cs. Also, adjusted the ActorRequestTimeout to a shorter duration and commented out the LegacyRequestTimeoutBehavior() in ProtoActorFeature.cs. These changes aim to enhance the efficiency and performance of the system.

* Refactor Workflow execution and ProtoActor interaction

This commit refactors the execution of workflows to manage re-entrancy and improve sequential calls. It also modifies the interaction model between ProtoActor grains and clients by following the ask-pattern. The ProtoWorkflowSubStatus enumeration has been extended to include a "Pending" state. The ActorRequestTimeout has been increased for better debugging.

* Remove unused queue and receive timeout in WorkflowGrain

The _executionQueue was initialized but never used in the WorkflowGrain class. This removal leads to cleaner and less confusing code. Additionally, the Context.SetReceiveTimeout method call has been removed from OnStarted method as it's no longer needed.

* Add ProtoActor to WorkflowServer runtime

In the WorkflowServer of Elsa Workflows Component Tests, the ProtoActor has been added to the runtime settings. This enhances the overall functionality and efficiency of the server.

* Add new component tests for Elsa.AzureServiceBus and remove old unit tests

In this commit, a new set of component tests for Elsa.AzureServiceBus have been added, providing more detailed and reliable testing. Simultaneously, several old unit test files and projects have been removed as they're no longer relevant or useful. These include tests in the 'Elsa.Workflows.Runtime.UnitTests1', 'Elsa.Activities.UnitTests' and 'Elsa.JavaScript.UnitTests' namespaces among others. The decision to remove these tests is motivated by the desire to streamline the testing process and focus on the most meaningful and reliable tests.

* Rename GlobalUsings.cs to Usings.cs in integration tests

Renamed the GlobalUsings.cs file to Usings.cs in the Elsa.Alterations.IntegrationTests project to better reflect its purpose. This change is intended to improve clarity within the codebase.

* Refactor Azure service bus testing setup to separate extension

This commit abstracts the setup for Azure service bus testing into a separate extension named AzureServiceBusServiceCollectionExtensions. The code has been removed from the WorkflowServer class, contributing to a cleaner and more modular codebase. This enhancement will facilitate better unit testing and reduce redundancy in test setup.

* Uncomment 'Description' and remove 'OptionsProvider' and 'OptionsMethod'

In the 'InputAttribute.cs' file, the 'Description' property has been uncommented to allow for a brief description of properties during workflow tooling. Furthermore, the 'OptionsProvider' and 'OptionsMethod' properties have been removed, simplifying the attribute options handling.

* Enable Azure Service Bus module

The change updates the 'useAzureServiceBusModule' constant from false to true in the Elsa.Server.Web Program.cs file. This adjustment allows the application to employ the Azure Service Bus module.

* Refactor ProtoActor module for workflow instance focus

The main changes in this commit revolve around renaming and refactoring to orient the ProtoActor module toward handling workflow instances. In the process, unnecessary imports have been removed, classes have been renamed to reflect their new focus on workflow instances, and various related elements such as protobuf files and services have also been renamed and refactored to align with these changes.

* Change AnalysisModeDocumentation to 'AllDisabledByDefault'

The AnalysisModeDocumentation setting in Directory.Build.props has been updated to 'AllDisabledByDefault' from 'Default'. This change disables all analysis by default in the documentation generation process.

* Update default value for Content and modify build properties

Modified the default value for the property 'Content' in the 'Message' class. Also updated the build properties by changing the 'AnalysisModeDocumentation' to "Default", disabling 'EnableTrimAnalyzer', and adding exception warning codes 'CS0162' and 'CS1591' to 'NoWarn'.

* Disable Azure Service Bus and initialize Customer fields

With this commit, the Azure Service Bus module usage has been turned off. In addition, the initial fields of the Customer entity have been set to their default values for safer initialization and to avoid potential null reference exceptions.

* Add distributed workflow services and configurations

Implemented basic functionalities in DistributedWorkflowClient and DistributedWorkflowRuntime. Updated Web Application 'Program.cs' to support different WorkflowRuntimes as per the configuration. Renamed WorkflowRuntimeFeature.cs to DistributedRuntimeFeature.cs and refactored the code accordingly. Removed unnecessary method 'UseDefaultWorkflowRuntime' from ModuleExtensions.cs.

* Refactor ReceivedServiceBusMessageModel from record to class

Converted ReceivedServiceBusMessageModel from a record to a class and updated relevant initialization code. Change was implemented because of the polymorphic serialization incabability of dealing with $type properties with records.

* Refactor WorkflowInstanceImpl for improved workflow management

This change refactors the WorkflowInstanceImpl class to improve workflow management. It implements queuing of RunWorkflowOptions while a workflow is running and ensures state before any workflow operations. Furthermore, workflow host creation is replaced with directly creating and managing workflow instances.

* Add DefaultFormattersFeature and update dependencies

A new feature, DefaultFormattersFeature, has been added to the Elsa.Common module. The WorkflowsFeature in the Elsa.Workflows.Core module has been updated to depend on this new feature. This will ensure that default JSON formatters are available across the application.

* Refactor JsonFormatter with JsonSerializerOptions property

Improved the JsonFormatter class by introducing a private JsonSerializerOptions property. The new implementation uses this property in the FromStringAsync method instead of initializing a new JsonSerializerOptions each time, improving efficiency. The JsonStringEnumConverter has also been moved to the class constructor.

* Refactor WorkflowInstanceImpl for improved code clarity

The refactor includes replacing direct field access with properties in multiple places for WorkflowGraph and WorkflowState. It also makes _queuedRunWorkflowOptions field readonly and removes unnecessary newline characters. These changes aim to improve readability, maintainability and encapsulation.

* Add and update methods to workflow instances

This commit introduces add and update functionalities to the workflow instances across the application. Additionally, it includes enhancements to the workflow execution, such as distributed locking and expanded logging capabilities for better debugging and tracking. Lastly, it introduces new configurations in application settings to fine-tune the workflow runtime environment.

* Refactor worker management in AzureServiceBus module

The codebase has been simplified by removing the unnecessary management of worker ref counts in the AzureServiceBus module. Previously, to manage worker instances, we kept a count of references to each worker and removed it when the count dropped to zero. This complexity has been entirely removed to make the module simpler and easier to maintain. Now we just create a worker when necessary, without tracking its usage across the codebase.

* Refactor workflow runtime with distributed locking and state checking

The workflow runtime has been refactored for better concurrency control and state management. The changes primarily include the introduction of distributed locking in action methods of the DistributedWorkflowClient and the handling of workflow instance states in the LocalWorkflowClient. This entails changes to the logic in the RunInstanceAsync, CreateAndRunInstanceAsync, CancelAsync, ExportStateAsync and ImportStateAsync methods.

* Refactor DispatchWorkflowInstance in MassTransitWorkflowDispatcher

The DispatchWorkflowInstance model in the MassTransitWorkflowDispatcher has been refactored. Previous detailed activity parameters (ActivityId, ActivityNodeId, ActivityInstanceId, ActivityHash) were replaced with a single ActivityHandle property. An additional Properties field was added.

* Update test in BulkDispatchWorkflowsTests

The DispatchAndWaitWorkflow test case in the BulkDispatchWorkflowsTests has been updated to use the new workflow client creation and instance running methods. Necessary namespace imports have also been added in the process to support the changes.

* Remove snapshot and persistence functionality from WorkflowInstanceImpl

This commit eliminates snapshot creation and persistence from the WorkflowInstanceImpl class. Methods related to these processes have been removed, including SaveSnapshotAsync(), ApplySnapshot(), and GetState(). This has also impacted the constructor and OnStarted() method where certain calls were made related to persistence. The need to manage and recover state asynchronously was eliminated, simplifying the implementation.

* Refactor workflow client implementations and update WorkflowStateMapper

Workflow clients in the modules Elsa.Workflows.Runtime and Elsa.ProtoActor have been refactored for better maintainability and readability. The WorkflowStateMapper in the Elsa.Workflows.Management is updated to include an "Apply" method, splitting the mapping functionality into smaller, more manageable methods. Also, usage of the Azure Service Bus Module in Elsa.Server.Web has been turned off.

* Update BulkDispatchWorkflowsTests specification

This commit updates the test specification in BulkDispatchWorkflowsTests by removing an unnecessary import and updating the WorkflowDefinitionHandle in the DispatchAndWaitWorkflow test method. Also, superfluous comments have been removed for readability.

* Update workflow definition in BulkDispatchWorkflowsTests

Changed the referenced workflow definition in the test scenario from EmployeeGreetingWorkflow to GreetEmployeesWorkflow. This update reflects more precise naming in our component tests for the BulkDispatchWorkflows scenario.

* Refactor BulkDispatchWorkflows and simplify error handling

The BulkDispatchWorkflows class in Elsa Workflows Runtime module has been refactored to simplify it. The detailed error handling with a list of errors has been removed and it is now directly dispatching child workflows without checking for a successful dispatch. The ProcessItem method has been removed which handled the errors previously, and the DispatchChildWorkflowAsync method no longer returns a dispatch response. This substantially simplifies the code and reduces its complexity.

* Update workflow runtime and distributed locking configuration settings

In the web server settings, the workflow runtime was changed from 'Distributed' to 'ProtoActor'. Also, the distributed lock provider setting has been moved into a new 'DistributedLocking' section in the configuration settings, allowing more detailed lock options to be set, including a lock acquisition timeout.

* Replace ProtoActor with DistributedRuntime in WorkflowServer

The current commit modifies our WorkflowServer configuration under our component tests. The "UseProtoActor" method which was previously used for runtime configuration has been commented out and replaced with "UseDistributedRuntime". This change suggests a shift towards a distributed runtime environment.

* Add new services and classes for workflow messaging

This commit adds new classes and services to facilitate workflow messaging. These include 'BroadcastWorkflowInboxMessageOptions', 'IWorkflowInbox', 'NewWorkflowInboxMessage', 'SubmitWorkflowInboxMessageResult', 'WorkflowInboxMessage', 'WorkflowInboxMessageDeliveryParams', and 'WorkflowInboxMessageFilter'. Additionally, changes were made in 'HttpWorkflowsMiddleware.cs' and 'WorkflowRuntimeFeature.cs' to use 'IWorkflowRunner' for executing workflows, and deprecated 'IWorkflowHostFactory' and 'WorkflowInvoker'. The messaging-related classes provide methods and properties to manage and manipulate workflow messages, delivery options and results. 'IWorkflowInbox' provides an interface for delivering messages to workflow instances while 'IWorkflowRunner' fulfills running workflows.

* Refactor WorkflowCancellationService for cleaner syntax

Aesthetic adjustments were made to the WorkflowCancellationService code to improve readability and maintainability. This includes tidying up line breaks, reformatting lists, correcting spelling in comments, and consolidating parameters in a function call.

* Remove unused import in MassTransitWorkflowCancellationDispatcher

The 'Elsa.Workflows.Runtime.Contracts' namespace was removed from the MassTransitWorkflowCancellationDispatcher file because it was not being utilized. This ensures a clean and efficient codebase by removing unnecessary imports.

* Remove Class1 from Elsa.Testing.Shared.Component

This commit deletes Class1.cs as it was no longer serving any purpose in the Elsa.Testing.Shared.Component. This removal helps keep the codebase clean and maintainable.

* Reduce default timeout in ISignalManager interface

The default millisecond timeout for the WaitAsync functions in the ISignalManager interface has been reduced from 5000ms to 1000ms. This change will speed up signal wait times in our testing framework.

* Refactor syntax representation in SendMessage activity

Simplified the syntax representation in the SendMesssage activity in the Elsa Azure Service Bus module. The SupportedSyntaxes property now utilizes a more concise array initialization.

* Removed obsolete 'Stimulus' property and adjusted consumers

The 'Stimulus' property in DispatchResumeWorkflows and DispatchTriggerWorkflowsRequest classes has been removed as it was marked obsolete. The DispatchWorkflowRequestConsumer has been adjusted to only use the 'BookmarkPayload' property. This ensures a cleaner code base and removes potential confusion between the properties.

* Rename GetNamedWorkflowGrain to GetNamedWorkflowInstanceClient

The method name GetNamedWorkflowGrain in both ProtoActorWorkflowClient and ClusterExtensions has been renamed to GetNamedWorkflowInstanceClient to improve code clarity. This change provides better semantics of what the function is purposed for.

* Remove unused snapshot classes

The commit removes the WorkflowGrainSnapshot and WorkflowInstanceGrainSnapshot classes from the Elsa.ProtoActor module. These classes were part of an older architecture and are no longer required.

* Remove unused field from Azure ServiceBus Worker

The _refCount field in the Worker class from the Azure ServiceBus module was unused. To maintain a clean codebase and improve readability, this field has been removed.

* Remove WorkflowInboxMessageRecord from Elsa.Dapper module

The commit includes the deletion of the entire WorkflowInboxMessageRecord class from Elsa.Dapper module. This file was managing various activities related to the workflow inbox messages, such as delivering messages to a workflow instance.

* Add new V3_2 migrations for all database providers

This commit introduces new V3_2 migrations for MySQL, SQLite, PostgreSQL, and SQLServer database providers. Included are `Up` and `Down` migrations, the corresponding Designer files, and specific Alterations and Runtime changes. SqlDbType specifications were also added for each.

* Refactor WorkflowDefinitionFilter and update related modules

Empty lines were removed between property declarations to improve readability in WorkflowDefinitionFilter. An error where 'filter.IsReadonly' was used instead of 'IsReadonly' was also corrected to ensure proper functionality. Additionally, WorkflowDefinitionFilter was imported in the Delete and Revert endpoint modules of the Elsa.Workflow.Api class to maintain consistency across the codebase.

* Change MongoUserStore to non-abstract class

The MongoUserStore class was previously tagged as an abstract class in the Identity module of Elsa.MongoDb. This update changes the MongoUserStore class from an abstract to a non-abstract (concrete) class to enable direct instantiation.

* Add ForwardedType attribute and update bookmarks

This commit introduces a new `ForwardedType` attribute to aid in forwarding types to new types when deserializing JSON. Additionally, the existing bookmarks related to workflow runtime activities have been updated. These changes also require modifying the `PolymorphicSerializer` in the Elsa.MongoDb project to handle types using the new `TypeHelper.GetLatestType` method.

* Fix logger reference in exception handling

The logger reference used in the catch block of the DefaultTriggerScheduler.cs file was incorrect. This commit corrects it by using the appropriate logger variable for logging any potential cron expression format errors.

* Refactor component tests and improve code cleanliness

This commit refactor the component tests, introduced new interfaces and events related to workflow definition and trigger change token signals. Removed an unused file, DictionaryExtensions.cs and refactored the GetOrAdd method to better handle null values. Some minor changes and improvements were also made in existing files to enhance overall code cleanliness.

---------

Co-authored-by: Steve Taylor <stevetayloruk@users.noreply.github.com>
2024-06-10 19:36:51 +02:00