diff --git a/apps/browser/src/platform/services/sdk/browser-sdk-client-factory.ts b/apps/browser/src/platform/services/sdk/browser-sdk-client-factory.ts index d3b8f36a540..f9cfde73aff 100644 --- a/apps/browser/src/platform/services/sdk/browser-sdk-client-factory.ts +++ b/apps/browser/src/platform/services/sdk/browser-sdk-client-factory.ts @@ -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 | 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 ): Promise { - 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((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); + }); + }); +};