bolt.diy/app/shared/lib/webcontainer/index.ts
KevIsDev 4d3222ee96 refactor: reorganize project structure by moving files to a more dev friendly setup
- Move stores/utils/types to their relative directories (i.e chat stores in chat directory)
- Move utility files to shared/utils
- Move component files to shared/components
- Move type definitions to shared/types
- Move stores to shared/stores
- Update import paths across the project
2025-06-16 15:33:59 +01:00

66 lines
2.2 KiB
TypeScript

import { WebContainer } from '@webcontainer/api';
import { WORK_DIR_NAME } from '~/shared/utils/constants';
import { cleanStackTrace } from '~/shared/utils/stacktrace';
interface WebContainerContext {
loaded: boolean;
}
export const webcontainerContext: WebContainerContext = import.meta.hot?.data.webcontainerContext ?? {
loaded: false,
};
if (import.meta.hot) {
import.meta.hot.data.webcontainerContext = webcontainerContext;
}
export let webcontainer: Promise<WebContainer> = new Promise(() => {
// noop for ssr
});
if (!import.meta.env.SSR) {
webcontainer =
import.meta.hot?.data.webcontainer ??
Promise.resolve()
.then(() => {
return WebContainer.boot({
coep: 'credentialless',
workdirName: WORK_DIR_NAME,
forwardPreviewErrors: true, // Enable error forwarding from iframes
});
})
.then(async (webcontainer) => {
webcontainerContext.loaded = true;
const { workbenchStore } = await import('~/shared/workbench/stores/workbench');
const response = await fetch('/inspector-script.js');
const inspectorScript = await response.text();
await webcontainer.setPreviewScript(inspectorScript);
// Listen for preview errors
webcontainer.on('preview-message', (message) => {
console.log('WebContainer preview message:', message);
// Handle both uncaught exceptions and unhandled promise rejections
if (message.type === 'PREVIEW_UNCAUGHT_EXCEPTION' || message.type === 'PREVIEW_UNHANDLED_REJECTION') {
const isPromise = message.type === 'PREVIEW_UNHANDLED_REJECTION';
const title = isPromise ? 'Unhandled Promise Rejection' : 'Uncaught Exception';
workbenchStore.actionAlert.set({
type: 'preview',
title,
description: 'message' in message ? message.message : 'Unknown error',
content: `Error occurred at ${message.pathname}${message.search}${message.hash}\nPort: ${message.port}\n\nStack trace:\n${cleanStackTrace(message.stack || '')}`,
source: 'preview',
});
}
});
return webcontainer;
});
if (import.meta.hot) {
import.meta.hot.data.webcontainer = webcontainer;
}
}