Ensure we await for the wasm module to load (#11995)
Webpack seems to always convert imports to be async. This causes a issue where init_sdk is not always initialized before we call it. To resolve this I added a promise we can await in MV3 mode, and also defined a timeout which throws an error we can use to identify if we have issues loading the module.
This commit is contained in:
parent
5da5c886ea
commit
ef127fd26e
|
@ -20,22 +20,28 @@ const supported = (() => {
|
|||
return false;
|
||||
})();
|
||||
|
||||
// Due to using webpack as bundler, sync imports will return an async module. Since we do support
|
||||
// top level awaits, we define a promise we can await in the `load` function.
|
||||
let loadingPromise: Promise<any> | undefined;
|
||||
|
||||
// Manifest v3 does not support dynamic imports in the service worker.
|
||||
if (BrowserApi.isManifestVersion(3)) {
|
||||
if (supported) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("WebAssembly is supported in this environment");
|
||||
import("./wasm");
|
||||
loadingPromise = import("./wasm");
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("WebAssembly is not supported in this environment");
|
||||
import("./fallback");
|
||||
loadingPromise = import("./fallback");
|
||||
}
|
||||
}
|
||||
|
||||
// Manifest v2 expects dynamic imports to prevent timing issues.
|
||||
async function load() {
|
||||
if (BrowserApi.isManifestVersion(3)) {
|
||||
// Ensure we have loaded the module
|
||||
await loadingPromise;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -59,8 +65,30 @@ export class BrowserSdkClientFactory implements SdkClientFactory {
|
|||
async createSdkClient(
|
||||
...args: ConstructorParameters<typeof BitwardenClient>
|
||||
): Promise<BitwardenClient> {
|
||||
await load();
|
||||
try {
|
||||
await loadWithTimeout();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to load: ${error.message}`);
|
||||
}
|
||||
|
||||
return Promise.resolve((globalThis as any).init_sdk(...args));
|
||||
}
|
||||
}
|
||||
|
||||
const loadWithTimeout = async () => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const timer = setTimeout(() => {
|
||||
reject(new Error("Operation timed out after 1 second"));
|
||||
}, 1000);
|
||||
|
||||
load()
|
||||
.then(() => {
|
||||
clearTimeout(timer);
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
clearTimeout(timer);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue