From 84cd1ccf0606f87a36a6c28cab4267011c471be5 Mon Sep 17 00:00:00 2001 From: Yan Chen <48968912+chenyan-dfinity@users.noreply.github.com> Date: Wed, 4 Sep 2024 11:11:36 -0700 Subject: [PATCH] wait for worker --- src/App.tsx | 56 +++++++++++++++++++++++++++++++++------------ src/index.jsx | 8 +++---- src/workers/file.ts | 7 +++--- src/workers/moc.ts | 15 ++++++++++++ 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 5426a205..51a93c9f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -61,9 +61,9 @@ const AppContainer = styled.div<{ candidWidth: string; consoleHeight: string }>` --consoleHeight: ${(props) => props.consoleHeight ?? 0}; `; -const worker = wrap( - new Worker(new URL("./workers/moc.ts", import.meta.url), { type: "module" }) -); +//const worker = wrap( +// new Worker(new URL("./workers/moc.ts", import.meta.url), { type: "module" }) +//); const urlParams = new URLSearchParams(window.location.search); const hasUrlParams = !!( urlParams.get("git") || @@ -71,7 +71,8 @@ const hasUrlParams = !!( urlParams.get("post") ); async function fetchFromUrlParams( - dispatch: (action: WorkplaceReducerAction) => void + worker, + dispatch: (action: WorkplaceReducerAction) => void, ): Promise | undefined> { const git = urlParams.get("git"); const tag = urlParams.get("tag"); @@ -103,7 +104,7 @@ async function fetchFromUrlParams( project.files.map((file) => { worker.Moc({ type: "save", file: file.name, content: file.content }); return [file.name, file.content]; - }) + }), ); if (project.packages.length) { for (const pack of project.packages[0]) { @@ -151,10 +152,11 @@ async function fetchFromUrlParams( } export function App() { + const [worker, setWorker] = useState(null); const [workplaceState, workplaceDispatch] = useReducer( workplaceReducer.reduce, {}, - workplaceReducer.init + workplaceReducer.init, ); const [isProjectModalOpen, setIsProjectModalOpen] = useState(!hasUrlParams); const [isFirstVisit, setIsFirstVisit] = useState(!hasUrlParams); @@ -195,7 +197,7 @@ export function App() { logger.log( `Use this link to access the code:\n${ window.location.origin - }/?tag=${hash.toString()}` + }/?tag=${hash.toString()}`, ); } @@ -218,11 +220,29 @@ export function App() { }, }); }, - [workplaceDispatch] + [workplaceDispatch], ); + useEffect(() => { + const initializeWorker = async () => { + const workerInstance = wrap( + new Worker(new URL("./workers/moc.ts", import.meta.url), { + type: "module", + }), + ); + + // Wait for the worker to be fully initialized + await workerInstance.waitForInitialization(); + + setWorker(workerInstance); + console.log("moc worker initialized"); + }; + + initializeWorker(); + }, []); // Add the Motoko package to allow for compilation / checking useEffect(() => { + if (!worker) return; const baseInfo = { name: "base", repo: "https://github.com/dfinity/motoko-base.git", @@ -231,7 +251,9 @@ export function App() { homepage: "https://sdk.dfinity.org/docs/base-libraries/stdlib-intro.html", }; (async () => { + console.log("fetching base package"); await worker.fetchPackage(baseInfo); + console.log("fetching done from worker"); await workplaceDispatch({ type: "loadPackage", payload: { @@ -243,7 +265,7 @@ export function App() { logger.log(`base library version ${baseInfo.version}`); // fetch code after loading base library if (hasUrlParams) { - const files = await fetchFromUrlParams(workplaceDispatch); + const files = await fetchFromUrlParams(worker, workplaceDispatch); if (files) { importCode(files); } else { @@ -252,20 +274,22 @@ export function App() { } })(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [worker]); useEffect(() => { (async () => { - setTTL((await backend.getInitParams()).canister_time_to_live); + await setTTL((await backend.getInitParams()).canister_time_to_live); + console.log("ttl", TTL); })(); }, []); useEffect(() => { + if (!worker) return; worker.Moc({ type: "setActorAliases", list: getActorAliases(workplaceState.canisters), }); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [workplaceState.canisters]); + }, [worker, workplaceState.canisters]); useEffect(() => { // Show Candid UI iframe if there are canisters @@ -276,6 +300,8 @@ export function App() { setCandidWidth(isCandidReady ? "30vw" : "0"); }, [workplaceState.canisters, workplaceState.selectedCanister]); + if (!worker) return
Loading...
; + return (
@@ -337,8 +363,8 @@ export function App() { // because message.caller can call other canisters to spawn new children. const nameMap = Object.fromEntries( Object.entries(workplaceState.canisters).map( - ([name, info]) => [info.id, name] - ) + ([name, info]) => [info.id, name], + ), ); Object.entries(workplaceState.canisters).forEach( async ([_, info]) => { @@ -359,7 +385,7 @@ export function App() { }); }); }); - } + }, ); }} /> diff --git a/src/index.jsx b/src/index.jsx index 4775d05b..dc186171 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,5 +1,5 @@ import React from "react"; -import ReactDOM from "react-dom"; +import { createRoot } from "react-dom/client"; import { App } from "./App"; import { Stats } from "./Stats"; import { ProvideLogging } from "./components/Logger"; @@ -8,20 +8,18 @@ import "./assets/styles/variables.css"; import "./assets/fonts/CircularXX.css"; if (window.location.pathname === "/stats") { - ReactDOM.render( + createRoot(document.getElementById("root")).render( , - document.getElementById("root"), ); } else { // TODO: if I use the new createRoot API, base library will not load properly, and there is no log of `moc` being loaded. - ReactDOM.render( + createRoot(document.getElementById("root")).render( , - document.getElementById("root"), ); } diff --git a/src/workers/file.ts b/src/workers/file.ts index 9022f9af..ae01ea8b 100644 --- a/src/workers/file.ts +++ b/src/workers/file.ts @@ -35,6 +35,7 @@ export async function fetchPackage(info: PackageInfo): Promise { ) { return false; } + console.log("HERE"); const repo: RepoInfo = { repo: info.repo.slice(0, -4).replace(/^(https:\/\/github.com\/)/, ""), branch: info.version, @@ -49,7 +50,7 @@ export async function fetchPackage(info: PackageInfo): Promise { export async function fetchGithub( repo: RepoInfo, - target_dir = "" + target_dir = "", ): Promise | undefined> { const possiblyCDN = !( (repo.branch.length % 2 === 0 && /^[A-F0-9]+$/i.test(repo.branch)) || @@ -74,7 +75,7 @@ export function saveWorkplaceToMotoko(files: Record) { async function fetchFromCDN( repo: RepoInfo, - target_dir = "" + target_dir = "", ): Promise | undefined> { const meta_url = `https://data.jsdelivr.com/v1/package/gh/${repo.repo}@${repo.branch}/flat`; const base_url = `https://cdn.jsdelivr.net/gh/${repo.repo}@${repo.branch}`; @@ -115,7 +116,7 @@ async function fetchFromCDN( async function fetchFromGithub( repo: RepoInfo, - target_dir = "" + target_dir = "", ): Promise | undefined> { const meta_url = `https://api.github.com/repos/${repo.repo}/git/trees/${repo.branch}?recursive=1`; const base_url = `https://raw.githubusercontent.com/${repo.repo}/${repo.branch}/`; diff --git a/src/workers/moc.ts b/src/workers/moc.ts index a24aaf2e..32036907 100644 --- a/src/workers/moc.ts +++ b/src/workers/moc.ts @@ -52,6 +52,20 @@ export function Moc(action: MocAction) { return Motoko.printDeps(action.file); } } +export function waitForInitialization() { + return new Promise((resolve) => { + if (Motoko) { + resolve(); + } else { + const checkInterval = setInterval(() => { + if (Motoko) { + clearInterval(checkInterval); + resolve(); + } + }, 100); + } + }); +} // Initialize Motoko when the worker starts loadMoc() @@ -66,6 +80,7 @@ loadMoc() fetchGithub, saveWorkplaceToMotoko, pow, + waitForInitialization, }); } else { console.error("Failed to initialize Motoko");