By design, the rhino3dm javascript package has to be initialized (rhino3dm().then(rhino => { // do rhino stuff })) before being used. This is a wasm limitation and is all fine. You can even store the value in the .then ‘callback’ to run wasm functionality synchronously afterwards.
I have been suffering in silence, though, because the emscripten tool generates a promise-like module that you cannot await.
Finally came across this issue and wanted to share a workaround that just made my day.
import rhino3dm from 'rhino3dm'
// In some async context
await rhino3dm().then(rhino => {
// Do something with rhino
delete rhino['then']
}
This feels like the most sinful javascript I’ve ever seen but it works, even after multiple calls. I store the rhino module somewhere and run things synchronously from there.
Thanks for the tip @Chuck_Driesler! I ran into this myself and it’s frustrating! We’ll have to experiment with the latest version of emscripten to see if it’ll resolve these issues for us as promised…
Perfect, thanks! I was now struggling with this for days! Every time I tried to use await, it got stuck in limbo, but now it finally resolves!
Since I’m using SvleteKit with dynamic routes, I wasn’t able to make it work with the npm package, but if someone comes over the same problem, here was my solution with the help of @Chuck_Driesler s input, hope it might help someone
function initRhino() {
// ref: https://github.com/mcneel/rhino3dm/blob/main/docs/javascript/RHINO3DM.JS.md
// ref: https://discourse.mcneel.com/t/await-rhino3dm-js-wasm-import/101585
return new Promise((resolve, reject) => {
// Check if Rhino3dm is already loaded
if (window.Rhino3dm) {
console.log('Rhino3dm is already loaded.');
resolve(window.Rhino3dm);
return;
}
// Create and append the script
const script = document.createElement('script');
script.src = 'https://files.mcneel.com/rhino3dm/js/latest/rhino3dm.js';
document.head.appendChild(script);
script.onerror = () => {
console.error('Failed to load the Rhino3dm script');
reject(new Error('Failed to load the Rhino3dm script'));
};
script.onload = () => {
console.log('Rhino3dm script loaded.');
if (typeof window.rhino3dm !== 'function') {
console.error('rhino3dm initialization function not found');
reject(new Error('rhino3dm initialization function not found'));
return;
}
let modulePromise = window.rhino3dm();
if (modulePromise && modulePromise.then) {
modulePromise.then((module) => {
console.log('Rhino3dm module loaded.', module);
delete module['then'];
resolve(module); // Resolve the promise with the Rhino3dm module
});
} else {
console.error('window.rhino3dm did not return a promise.');
reject(new Error('window.rhino3dm did not return a promise.'));
}
};
});
}