mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
- Add support for `PREVIEW_CONSOLE_ERROR` in WebContainer error handling - Introduce new Search component for text search functionality - Extend `ScrollPosition` interface to include `line` and `column` - Implement scroll-to-line functionality in CodeMirrorEditor - Add tab-based navigation for files and search in EditorPanel This commit introduces several enhancements to the editor, including improved error handling, better scrolling capabilities, and a new search feature. The changes are focused on improving the user experience and adding new functionality to the editor components.
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import { WebContainer } from '@webcontainer/api';
|
|
import { WORK_DIR_NAME } from '~/utils/constants';
|
|
import { cleanStackTrace } from '~/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('~/lib/stores/workbench');
|
|
|
|
// 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' ||
|
|
message.type === 'PREVIEW_CONSOLE_ERROR'
|
|
) {
|
|
const isPromise = message.type === 'PREVIEW_UNHANDLED_REJECTION';
|
|
const isConsoleError = message.type === 'PREVIEW_CONSOLE_ERROR';
|
|
const title = isPromise
|
|
? 'Unhandled Promise Rejection'
|
|
: isConsoleError
|
|
? 'Console Error'
|
|
: 'Uncaught Exception';
|
|
workbenchStore.actionAlert.set({
|
|
type: 'preview',
|
|
title,
|
|
description:
|
|
'message' in message
|
|
? message.message
|
|
: 'args' in message && Array.isArray(message.args) && message.args.length > 0
|
|
? message.args[0]
|
|
: '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;
|
|
}
|
|
}
|