I haven‘t looked what ScriptEngineManager does, but the AbstractScriptModuleHandler asks the ScriptEnginerManager to create an engine for the script type and uses a random UUID as the engine identifier, so (as longs as there is no UUID collision, which is highly unlikely) each ScriptActionHandler and each ScriptConditionHandler uses its own script engine.
As openHAB‘s scripting architecture is designed around the ScriptEngine interface, it makes sense to simply provide a ScriptEngine implementation based on GraalJS. And the general script engine architecture is there since the experimental rule engine was added in openHAB 2.4 or something like that IIRC.
The GraalJSScriptEngine is basically a wrapper around a GraalVM Polyglot Context, and the GraalVM Polylot Engine used under the hood is already shared across all GraalJSScriptEngines. FYI, Python Scripting provides no ScriptEngine implementation, so @holger_hees simply build one around the GraalVM Polyglot Context.
And as we need separate contexts, we can also keep separate engines.
I think you refer to what I implemented in https://github.com/openhab/openhab-addons/pull/14135. We load the helper library into a org.graalvm.polyglot.Source, which then is shared across all places where we inject the helper library. Since we share the underlying Polyglot Engine, there is some caching and sharing, which also speeds up helper library injection.
Please note the difference between a ScriptEngine and a GraalVM Polyglot Engine. I know the wording is quite confusing, but ScriptEngine is the interface and expected by openHAB Core, GraalVM Polyglot Engine is something used internally by Graal to run the code.
They are around that. Python Scripting is only wrapping a context to provide a ScriptEngine compliant implementation, for JS Graal was so kind to do that.