Skip to content

Commit 6c4e8b1

Browse files
committed
fix: base64 stack overflow and Monaco editor error handling
- Process bytes in chunks in encodeBase64() to avoid call stack overflow on large files - Add Monaco loader configuration for bundled assets - Add loading state to Editor components - Show actual token in Python example (enables Ctrl+A copy) - Use bytes literal in set_file example
1 parent 077dfab commit 6c4e8b1

4 files changed

Lines changed: 19 additions & 5 deletions

File tree

frontend/src/lib/base64.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
/**
22
* Encode a string to base64
3+
* Processes bytes in chunks to avoid call stack overflow with large data
34
*/
45
export function encodeBase64(str: string): string {
56
const bytes = new TextEncoder().encode(str);
6-
return btoa(String.fromCharCode(...bytes));
7+
// Process in chunks to avoid call stack overflow with spread operator
8+
const CHUNK_SIZE = 0x8000; // 32KB chunks
9+
let binary = "";
10+
for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
11+
const chunk = bytes.subarray(i, i + CHUNK_SIZE);
12+
binary += String.fromCharCode.apply(null, chunk as unknown as number[]);
13+
}
14+
return btoa(binary);
715
}
816

917
/**

frontend/src/main.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
66
import { BrowserRouter } from "react-router-dom";
77
import { Toaster } from "sonner";
88
import * as Sentry from "@sentry/react";
9+
import { loader } from "@monaco-editor/react";
910
import App from "./App";
1011
import "./index.css";
1112
import "flag-icons/css/flag-icons.min.css";
1213

14+
// Configure Monaco loader to use bundled assets
15+
loader.config({
16+
"vs/nls": { availableLanguages: { "*": "en" } },
17+
});
18+
1319
// Initialize Sentry for error tracking (if DSN is configured at runtime)
1420
// Config is injected into index.html by the backend at runtime
1521
declare global {

frontend/src/pages/RequestsPage.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ request = repo.get_http_request()
2929
print(request.method, request.path, request.headers)
3030
3131
# Set a custom HTTP response
32-
repo.set_file("index.html", "<h1>Hello from RequestRepo!</h1>", status_code=200)
32+
repo.set_file("index.html", b"<h1>Hello from RequestRepo!</h1>", status_code=200)
3333
3434
# Add DNS records
3535
repo.add_dns("*", "A", "1.2.3.4") # Wildcard for all sub-subdomains
@@ -165,10 +165,9 @@ export function RequestsPage() {
165165
theme={resolvedTheme === "dark" ? "vs-dark" : "light"}
166166
value={PYTHON_EXAMPLE.replace(
167167
/TOKEN_HERE/g,
168-
session?.token
169-
? "********************************"
170-
: "<your_token>",
168+
session?.token || "<your_token>",
171169
).replace(/SUBDOMAIN_HERE/g, subdomain)}
170+
loading={<div className="p-4 text-default-500">Loading editor...</div>}
172171
options={{
173172
readOnly: true,
174173
minimap: { enabled: false },

frontend/src/pages/ResponseEditorPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ export function ResponseEditorPage() {
358358
theme={resolvedTheme === "dark" ? "vs-dark" : "light"}
359359
value={content}
360360
onChange={(value) => setContent(value ?? "")}
361+
loading={<div className="p-4 text-default-500">Loading editor...</div>}
361362
options={{
362363
minimap: { enabled: false },
363364
fontSize: 13,

0 commit comments

Comments
 (0)