Merge branch 'feat/e2b' of https://github.com/jamesmurdza/sandbox into feat/e2b

This commit is contained in:
Akhilesh Rangani 2024-06-16 15:19:13 -04:00
commit 186d765682
3 changed files with 23 additions and 2 deletions

View File

@ -132,18 +132,27 @@ io.on("connection", async (socket) => {
if (!containers[data.sandboxId]) { if (!containers[data.sandboxId]) {
containers[data.sandboxId] = await Sandbox.create(); containers[data.sandboxId] = await Sandbox.create();
console.log("Created container ", data.sandboxId); console.log("Created container ", data.sandboxId);
io.emit("previewURL", "https://" + containers[data.sandboxId].getHostname(5173));
} }
} catch (error) { } catch (error) {
console.error("Error creating container ", data.sandboxId, error); console.error("Error creating container ", data.sandboxId, error);
} }
}); });
// Change the owner of the project directory to user
const fixPermissions = async () => {
await containers[data.sandboxId].process.startAndWait(
`sudo chown -R user "${path.join(dirName, "projects", data.sandboxId)}"`
);
}
const sandboxFiles = await getSandboxFiles(data.sandboxId); const sandboxFiles = await getSandboxFiles(data.sandboxId);
sandboxFiles.fileData.forEach(async (file) => { sandboxFiles.fileData.forEach(async (file) => {
const filePath = path.join(dirName, file.id); const filePath = path.join(dirName, file.id);
await containers[data.sandboxId].filesystem.makeDir(path.dirname(filePath)); await containers[data.sandboxId].filesystem.makeDir(path.dirname(filePath));
await containers[data.sandboxId].filesystem.write(filePath, file.data); await containers[data.sandboxId].filesystem.write(filePath, file.data);
}); });
fixPermissions();
socket.emit("loaded", sandboxFiles.files); socket.emit("loaded", sandboxFiles.files);
@ -177,6 +186,7 @@ io.on("connection", async (socket) => {
file.data = body; file.data = body;
await containers[data.sandboxId].filesystem.write(path.join(dirName, file.id), body); await containers[data.sandboxId].filesystem.write(path.join(dirName, file.id), body);
fixPermissions();
await saveFile(fileId, body); await saveFile(fileId, body);
} catch (e) { } catch (e) {
io.emit("rateLimit", "Rate limited: file saving. Please slow down."); io.emit("rateLimit", "Rate limited: file saving. Please slow down.");
@ -195,6 +205,7 @@ io.on("connection", async (socket) => {
path.join(dirName, fileId), path.join(dirName, fileId),
path.join(dirName, newFileId) path.join(dirName, newFileId)
) )
fixPermissions();
file.id = newFileId; file.id = newFileId;
@ -221,6 +232,7 @@ io.on("connection", async (socket) => {
const id = `projects/${data.sandboxId}/${name}`; const id = `projects/${data.sandboxId}/${name}`;
await containers[data.sandboxId].filesystem.write(path.join(dirName, id), ""); await containers[data.sandboxId].filesystem.write(path.join(dirName, id), "");
fixPermissions();
sandboxFiles.files.push({ sandboxFiles.files.push({
id, id,
@ -273,6 +285,7 @@ io.on("connection", async (socket) => {
path.join(dirName, fileId), path.join(dirName, fileId),
path.join(dirName, newFileId) path.join(dirName, newFileId)
) )
fixPermissions();
await renameFile(fileId, newFileId, file.data); await renameFile(fileId, newFileId, file.data);
} catch (e) { } catch (e) {
io.emit("rateLimit", "Rate limited: file renaming. Please slow down."); io.emit("rateLimit", "Rate limited: file renaming. Please slow down.");

View File

@ -94,6 +94,9 @@ export default function CodeEditor({
}[] }[]
>([]) >([])
// Preview state
const [previewURL, setPreviewURL] = useState<string>("");
const isOwner = sandboxData.userId === userData.id const isOwner = sandboxData.userId === userData.id
const clerk = useClerk() const clerk = useClerk()
@ -413,6 +416,7 @@ export default function CodeEditor({
socketRef.current?.on("rateLimit", onRateLimit) socketRef.current?.on("rateLimit", onRateLimit)
socketRef.current?.on("terminalResponse", onTerminalResponse) socketRef.current?.on("terminalResponse", onTerminalResponse)
socketRef.current?.on("disableAccess", onDisableAccess) socketRef.current?.on("disableAccess", onDisableAccess)
socketRef.current?.on("previewURL", setPreviewURL)
return () => { return () => {
socketRef.current?.off("connect", onConnect) socketRef.current?.off("connect", onConnect)
@ -421,6 +425,7 @@ export default function CodeEditor({
socketRef.current?.off("rateLimit", onRateLimit) socketRef.current?.off("rateLimit", onRateLimit)
socketRef.current?.off("terminalResponse", onTerminalResponse) socketRef.current?.off("terminalResponse", onTerminalResponse)
socketRef.current?.off("disableAccess", onDisableAccess) socketRef.current?.off("disableAccess", onDisableAccess)
socketRef.current?.off("previewURL", setPreviewURL)
} }
// }, []); // }, []);
}, [terminals]) }, [terminals])
@ -769,6 +774,7 @@ export default function CodeEditor({
previewPanelRef.current?.expand() previewPanelRef.current?.expand()
setIsPreviewCollapsed(false) setIsPreviewCollapsed(false)
}} }}
src={previewURL}
/> />
</ResizablePanel> </ResizablePanel>
<ResizableHandle /> <ResizableHandle />

View File

@ -15,9 +15,11 @@ import { toast } from "sonner"
export default function PreviewWindow({ export default function PreviewWindow({
collapsed, collapsed,
open, open,
src
}: { }: {
collapsed: boolean collapsed: boolean
open: () => void open: () => void
src: string
}) { }) {
const ref = useRef<HTMLIFrameElement>(null) const ref = useRef<HTMLIFrameElement>(null)
const [iframeKey, setIframeKey] = useState(0) const [iframeKey, setIframeKey] = useState(0)
@ -45,7 +47,7 @@ export default function PreviewWindow({
<PreviewButton <PreviewButton
onClick={() => { onClick={() => {
navigator.clipboard.writeText(`http://localhost:5173`) navigator.clipboard.writeText(src)
toast.info("Copied preview link to clipboard") toast.info("Copied preview link to clipboard")
}} }}
> >
@ -73,7 +75,7 @@ export default function PreviewWindow({
ref={ref} ref={ref}
width={"100%"} width={"100%"}
height={"100%"} height={"100%"}
src={`http://localhost:5173`} src={src}
/> />
</div> </div>
)} )}