diff --git a/src/lib/utils/helpers.ts b/src/lib/utils/helpers.ts index 558b4b1..87e0ccc 100644 --- a/src/lib/utils/helpers.ts +++ b/src/lib/utils/helpers.ts @@ -26,3 +26,11 @@ export const isUpgradeable = (sources?: ContractSources) => { if (!sources) return false; return Object.keys(sources).some((path) => path.includes('@openzeppelin/contracts-upgradeable')); } + +export const debouncer = (fn: (...args: any[]) => void, delay: number) => { + let timeout: NodeJS.Timeout; + return (...args: any[]) => { + clearTimeout(timeout); + timeout = setTimeout(() => fn(...args), delay); + }; +} diff --git a/src/lib/wizard/components/Deploy.svelte b/src/lib/wizard/components/Deploy.svelte index 8328a13..97c44ed 100644 --- a/src/lib/wizard/components/Deploy.svelte +++ b/src/lib/wizard/components/Deploy.svelte @@ -9,13 +9,16 @@ import { addAPToDropdown, findDeploymentEnvironment, globalState } from "$lib/state/state.svelte"; import { attempt } from "$lib/utils/attempt"; import { encodeConstructorArgs, getConstructorInputsWizard, getContractBytecode } from "$lib/utils/contracts"; - import { isMultisig, isUpgradeable } from "$lib/utils/helpers"; + import { debouncer, isMultisig, isUpgradeable } from "$lib/utils/helpers"; import Button from "./shared/Button.svelte"; import Input from "./shared/Input.svelte"; import Message from "./shared/Message.svelte"; + // debounce the compile call to avoid sending too many requests while the user is editing. + const compileDebounced = debouncer(compile, 600); + let inputsWithValue = $state>({}); - let busy = $state(false); + let isDeploying = $state(false); let successMessage = $state(""); let errorMessage = $state(""); let compilationError = $state(""); @@ -24,6 +27,7 @@ let deploymentResult = $state(undefined); let isDeterministic = $state(false); let salt: string = $state(""); + let isCompiling = $state(false); let contractBytecode = $derived.by(() => { if (!globalState.contract?.target || !compilationResult) return; @@ -61,12 +65,12 @@ : undefined ); - let inputs: ABIParameter[] = $state([]); $effect(() => { if (globalState.contract?.source?.sources) { - compile(); + isCompiling = true; + compileDebounced(); } }); @@ -75,7 +79,7 @@ inputsWithValue[target.name] = target.value; } - async function compile() { + async function compile(): Promise { const sources = globalState.contract?.source?.sources; if (!sources) { return; @@ -94,6 +98,7 @@ if (globalState.contract?.target && compilationResult) { inputs = getConstructorInputsWizard(globalState.contract.target, compilationResult.output.contracts); } + isCompiling = false; } function displayMessage(message: string, type: "success" | "error") { @@ -304,9 +309,9 @@ }; async function triggerDeploy() { - busy = true; + isDeploying = true; await deploy(); - busy = false; + isDeploying = false; } @@ -316,7 +321,9 @@ {/if} - {#if inputs.length > 0} + {#if isCompiling} + + {:else if inputs.length > 0}
Constructor Arguments
{#each inputs as input} @@ -352,7 +359,7 @@ {/if} -