This type of error can be caused by a gotcha with the Sandbox used inside the Function node.
The Sandbox gets its very own instance of Object. That means the prototype of an object created inside the Function node will not be the exact same thing as the prototype of the Object outside of the Sandbox.
The prototypes will be identical - but they will be separate instances of it - so the strict equality check will fail.
var plotlyConfig = {};
plotlyConfig.layout = {};
// Then the layout property is filled with sub-properties ...
Damn, don't know how you do it...
You are getting very warm ...
Plotly is made to run in the browser. But if you want to run it on the server - like we do for some features like validations - I needed to load it into JsDom. And JsDom uses the vm package, just like the function node:
Then it probably won't be easy to workaround this ...
It seems that I can get access to Plotly's internal vm context.
Perhaps I can use that (somehow) to create my instance inside the vm, to make sure it gets the correct prototype.
Something like this:
const createInstanceScript = new Script(`
var plotlyConfig = {};
plotlyConfig.layout = {};
// Then the layout property is filled with sub-properties ...
`);
const jsDomVmContext = dom.getInternalVMContext();
createInstanceScript.runInContext(jsDomVmContext );
Although then I don't have access to my variable from my node ...
My time is up for today. If somebody has any ideas meanwhile, please let me know.
I managed to workaround it.
Here is the code, but I assume there is no poor soul on this planet that will ever need it ...
Anyway:
// Script to create a global variable
const script = new vm.Script(`
this.plotlyConfig = {};
`);
// Execute the script in the VM, so that the global variable will be created in the VM context
const vmContext = jsDomInstance.getInternalVMContext();
script.runInContext(vmContext);
// Get the global variable from the VM context
var plotlyConfig = jsDomInstance.window.plotlyConfig;
// Manipulate the content of the global variable in the Node-RED node
plotlyConfig.someProperty = "someValue";
// Now you can call a function of the VM, and pass the plotlyConfig variable as a parameter ...
Since the variable has been created inside the VM context, its prototype will get through the check inside the VM ...
Without Nicks comment, I would most probably never have found the root cause in my current life ...
The code snippet in my last post worked fine for a few objects. But I needed to add a large number of objects and arrays. And all those also needed to have a prototype from the VM, and I don't know in advance how much properties the user will add
So instead of creating a fixed number of instances in the VM, I got an idea to add two functions to the VM context. One function to create an object in the VM, and one to create an array in the VM:
// Script to add global functions (to create a Javascript object or array) in the server DOM context
const script = new vm.Script(`
function createObject() {
return {};
}
function createArray() {
return [];
}
`);
// Execute the script in the VM (of jsDom), so that the global function is added to the VM context
const vmContext = ´jsDomInstance.getInternalVMContext();
script.runInContext(vmContext);
Now in my node I can do this all over the place:
Replace someVar = {} by someVar = jsDomInstance.window.createObject()
Replace someVar = [] by someVar = jsDomInstance.window.createArray()