ProtectedconstructorProtectedDefaultEngine-default wall-clock timeout applied to any action whose
MaxExecutionTimeMS is NULL. Intentionally generous (2 hours) because
some integration actions do legitimately long sync work; per-action
overrides should be used to tighten this for anything agent-facing.
Sub-classes can override to globally change the default.
True once the underlying ActionEngineBase cache has loaded.
StaticInstanceEnsures the single ActionEngineBase metadata cache is loaded. Delegates entirely to the base — ActionEngineServer holds no metadata of its own.
OptionalcontextUser: UserInfoOptionalprovider: IMetadataProviderProtectedEndProtectedGetThe Global Object Store is a place to store global objects that need to be shared across the application. Depending on the execution environment, this could be the window object in a browser, or the global object in a node environment, or something else in other contexts. The key here is that in some cases static variables are not truly shared because it is possible that a given class might have copies of its code in multiple paths in a deployed application. This approach ensures that no matter how many code copies might exist, there is only one instance of the object in question by using the Global Object Store.
ProtectedInternalOptionalinputSnapshot: stringProtectedParamThe ActionParam definition rows for the action being run — the source of each parameter's
LogValue flag. Read from the shared ActionEngineBase cache rather than off params.Action,
which is typed as the plain entity and carries no params collection.
ProtectedResolveHow much of this run to log, from the Entity Action binding that dispatched it. Direct invocations have no binding and therefore always log — the pre-existing behaviour.
ProtectedRunWraps InternalRunAction() with a universal wall-clock timeout
(Action.MaxExecutionTimeMS, falling back to DefaultActionTimeoutMS)
and an AbortSignal passed to the action via params.AbortSignal.
Enforcement is cooperative: when the timeout fires we set an abort on
the signal so in-flight fetch/setTimeout/custom polling logic can
short-circuit, and we race the action against a rejection that surfaces
a TIMEOUT result. If the caller already supplied an AbortSignal
(e.g. when being run from a Runtime-action bridge that has its own
abort), we chain to it so either source can trigger cancellation.
OptionalinputSnapshot: stringProtectedRunResolves and runs a Custom / Generated action via the ClassFactory.
This is the pre-existing path — factored out of InternalRunAction so
the Type dispatch is readable.
ProtectedRunThis method runs any filters for the action. Subclasses can override this method to provide custom filter logic.
ProtectedRunRuns an Action.Type='Runtime' action by delegating to the sandboxed
RuntimeActionExecutor. Approval / Status / Code-presence checks are
enforced inside the executor; here we parse the RuntimeActionConfiguration,
build the permissioned bridge-handler map, and hand it off.
The bridge handlers run in-process on the host (not inside the sandbox)
so they have full access to Metadata, RunView, ActionEngine, etc.
Permission enforcement against RuntimeActionConfiguration.permissions
happens inside each handler — see RuntimeActionBridge.ts.
If the configuration is missing or malformed, we still let the action
run in pure-compute mode (no bridge). The action's Code can then only
use input + libs; any attempt to call utilities.* at runtime
rejects with a "handler not registered" error from the worker pool.
ProtectedRunRuns a single Action Filter and returns whether the action should proceed.
Resolution order:
Code column — JavaScript that evaluates to true (allow) or
false (prevent), per the column contract — is compiled once per filter row version and
executed with an ActionFilterContext argument. The code may return its verdict
or assign ActionFilterContext.result.Failure semantics are FAIL-CLOSED: a filter that throws, yields a non-boolean, or has no evaluable logic prevents the action and logs the reason. A broken gate must not silently allow execution — silently allowing everything is precisely the pre-fix bug this replaces.
Subclasses can still override this method entirely to provide custom filter logic.
ProtectedShouldWhether a completed run should leave a log row, honouring both the caller's SkipActionLog and
the binding's LoggingMode. FailuresOnly exists for high-frequency bindings whose successful
runs would otherwise dominate the log table; a failure is always written.
ProtectedSnapshotThe as-called input parameters, redacted and serialized, for ActionExecutionLog.Params.
Taken once, at the top of RunAction, before the action can mutate its own parameter
array. Custom and Generated actions write outputs back into the very array they were handed, so a
snapshot taken any later — inside StartActionLog, or on the timeout path — is a post-hoc capture
of a mutated array masquerading as "what it was called with".
Every value passes through RedactParamsToJSON first: this method is the only producer of
the Params column, so redaction here is what makes the column safe by construction.
ProtectedStampWrites the Entity Action provenance onto a log row: which binding fired, from which lifecycle event, against which record. All four columns are NULL for a direct invocation, and that NULL is meaningful — it is how "nobody configured this, some code called it" reads in the log.
ProtectedStartOptionalinputSnapshot: stringProtectedStartOptionalinputSnapshot: stringProtectedValidateThis method handles input validation. Subclasses can override this method to provide custom input validation.
Protected StaticgetReturns the singleton instance of the class. If the instance does not exist, it is created and stored in the Global Object Store. If className is provided it will be used as part of the key in the Global Object Store, otherwise the actual class name will be used. NOTE: the class name used by default is the lowest level of the object hierarchy, so if you have a class that extends another class, the lowest level class name will be used.
OptionalclassName: string
Base class for executing actions. This class can be sub-classed if desired if you would like to modify the logic across ALL actions. To do so, sub-class this class and use the
Register Class
decorator from the @memberjunction/global package to register your sub-class with the ClassFactory. This will cause your sub-class to be used instead of this base class when the Metadata object insantiates the ActionEngine.