Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 70 additions & 13 deletions src/components/ProgramLoader/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ import { setIsProgramEditMode } from "@/store/debugger/debuggerSlice.ts";
import { selectIsAnyWorkerLoading } from "@/store/workers/workersSlice";
import { isSerializedError } from "@/store/utils";
import { ProgramFileUpload } from "@/components/ProgramLoader/ProgramFileUpload.tsx";
import { bytes } from "@typeberry/block";
import { selectInitialState } from "@/store/debugger/debuggerSlice.ts";
import { decodeStandardProgram } from "@typeberry/pvm-debugger-adapter";
import { RegistersArray } from "@/types/pvm.ts";

export const Loader = ({ setIsDialogOpen }: { setIsDialogOpen?: (val: boolean) => void }) => {
const dispatch = useAppDispatch();
const initialState = useAppSelector(selectInitialState);
const [programLoad, setProgramLoad] = useState<ProgramUploadFileOutput>();
const [error, setError] = useState<string>();
const [isSubmitted, setIsSubmitted] = useState(false);
Expand All @@ -22,23 +27,75 @@ export const Loader = ({ setIsDialogOpen }: { setIsDialogOpen?: (val: boolean) =
setError("");
}, [isLoading]);

const handleLoad = useCallback(async () => {
setIsSubmitted(true);
if (!programLoad) return;
const handleLoad = useCallback(
async (_event: unknown, program?: ProgramUploadFileOutput) => {
setIsSubmitted(true);

dispatch(setIsProgramEditMode(false));
if (!programLoad && !program) return;

try {
await debuggerActions.handleProgramLoad(programLoad);
setIsDialogOpen?.(false);
} catch (error) {
if (error instanceof Error || isSerializedError(error)) {
setError(error.message);
} else {
setError("Unknown error occured");
dispatch(setIsProgramEditMode(false));

try {
await debuggerActions.handleProgramLoad(program || programLoad);
setIsDialogOpen?.(false);
} catch (error) {
if (error instanceof Error || isSerializedError(error)) {
setError(error.message);
} else {
setError("Unknown error occurred");
}
}
},
[dispatch, programLoad, debuggerActions, setIsDialogOpen],
);

useEffect(() => {
const searchParams = new URLSearchParams(window.location.search);

if (searchParams.get("program")) {
const program = searchParams.get("program");

try {
// Add 0x prefix if it's not there - we're assuming it's the hex program either way
const hexProgram = program?.startsWith("0x") ? program : `0x${program}`;
const parsedBlob = bytes.BytesBlob.parseBlob(hexProgram ?? "");
const parsedBlobArray = Array.prototype.slice.call(parsedBlob.raw);

if (searchParams.get("flavour") === "jam") {
try {
const { code, /*memory,*/ registers } = decodeStandardProgram(parsedBlob.raw, new Uint8Array());

handleLoad({
program: Array.from(code),
name: "custom",
initial: {
regs: Array.from(registers) as RegistersArray,
pc: 0,
pageMap: [],
// TODO: map memory properly
// memory: [...memory],
gas: 10000n,
},
});
} catch (e) {
console.warn("Could not load the program from URL", e);
}
} else {
handleLoad(undefined, {
program: parsedBlobArray,
name: "custom",
initial: initialState,
});
}

window.history.replaceState({}, document.title, "/");
} catch (e) {
console.warn("Could not parse the program from URL", e);
}
}
}, [dispatch, programLoad, debuggerActions, setIsDialogOpen]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<>
<Tabs className="flex-1 flex flex-col items-start overflow-auto" defaultValue="upload">
Expand Down
11 changes: 5 additions & 6 deletions src/components/ProgramLoader/ProgramFileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { mapUploadFileInputToOutput } from "./utils";
import { decodeStandardProgram } from "@typeberry/pvm-debugger-adapter";
import { RegistersArray } from "@/types/pvm.ts";
import { SafeParseReturnType, z } from "zod";
import { useAppSelector } from "@/store/hooks";
import { selectInitialState } from "@/store/debugger/debuggerSlice";

const validateJsonTestCaseSchema = (json: unknown) => {
const pageMapSchema = z.object({
Expand Down Expand Up @@ -58,6 +60,8 @@ export const ProgramFileUpload = ({
onParseError: (error: string) => void;
close?: () => void;
}) => {
const initialState = useAppSelector(selectInitialState);

let fileReader: FileReader;

const handleFileRead = (e: ProgressEvent<FileReader>) => {
Expand Down Expand Up @@ -102,12 +106,7 @@ export const ProgramFileUpload = ({
onFileUpload({
program: Array.from(uint8Array),
name: "custom",
initial: {
regs: Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) as RegistersArray,
pc: 0,
pageMap: [],
gas: 10000n,
},
initial: initialState,
});
}
}
Expand Down
Loading