diff --git a/packages/browser-repl/src/components/shell.spec.tsx b/packages/browser-repl/src/components/shell.spec.tsx index a2cd7fd67..0d4a8a265 100644 --- a/packages/browser-repl/src/components/shell.spec.tsx +++ b/packages/browser-repl/src/components/shell.spec.tsx @@ -393,13 +393,11 @@ describe('shell', function () { await listener?.onPrint?.([{ type: null, printable: 42 }]); await waitFor(() => { - expect(output).to.deep.equal([ - { - format: 'output', - type: null, - value: 42, - }, - ]); + expect(output[output.length - 1]).to.deep.equal({ + format: 'output', + type: null, + value: 42, + }); }); }); diff --git a/packages/browser-repl/src/components/shell.tsx b/packages/browser-repl/src/components/shell.tsx index 2b25adada..18e4f0626 100644 --- a/packages/browser-repl/src/components/shell.tsx +++ b/packages/browser-repl/src/components/shell.tsx @@ -208,6 +208,9 @@ const _Shell: ForwardRefRenderFunction = ( const editorRef = useRef(null); const shellInputContainerRef = useRef(null); + const initialEvaluateRef = useRef(initialEvaluate); + const outputRef = useRef(output); + const historyRef = useRef(history); useImperativeHandle( ref, @@ -256,7 +259,7 @@ const _Shell: ForwardRefRenderFunction = ( return { onPrint: (result: RuntimeEvaluationResult[]): void => { const newOutput = [ - ...(output ?? []), + ...(outputRef.current ?? []), ...result.map( (entry): ShellOutputEntry => ({ format: 'output', @@ -267,6 +270,7 @@ const _Shell: ForwardRefRenderFunction = ( ]; capLengthEnd(newOutput, maxOutputLength); + outputRef.current = newOutput; onOutputChanged?.(newOutput); }, onPrompt: async ( @@ -300,10 +304,11 @@ const _Shell: ForwardRefRenderFunction = ( return ret; }, onClearCommand: (): void => { + outputRef.current = []; onOutputChanged?.([]); }, }; - }, [focusEditor, maxOutputLength, onOutputChanged, output]); + }, [focusEditor, maxOutputLength, onOutputChanged]); const updateShellPrompt = useCallback(async (): Promise => { let newShellPrompt = '>'; @@ -370,8 +375,8 @@ const _Shell: ForwardRefRenderFunction = ( const onInput = useCallback( async (code: string) => { - const newOutput = [...(output ?? [])]; - const newHistory = [...(history ?? [])]; + const newOutput = [...(outputRef.current ?? [])]; + const newHistory = [...(historyRef.current ?? [])]; // don't evaluate empty input, but do add it to the output if (!code || code.trim() === '') { @@ -380,6 +385,7 @@ const _Shell: ForwardRefRenderFunction = ( value: ' ', }); capLengthEnd(newOutput, maxOutputLength); + outputRef.current = newOutput; onOutputChanged?.(newOutput); return; } @@ -390,6 +396,7 @@ const _Shell: ForwardRefRenderFunction = ( value: code, }); capLengthEnd(newOutput, maxOutputLength); + outputRef.current = newOutput; onOutputChanged?.(newOutput); const outputLine = await evaluate(code); @@ -397,6 +404,7 @@ const _Shell: ForwardRefRenderFunction = ( // add output to output newOutput.push(outputLine); capLengthEnd(newOutput, maxOutputLength); + outputRef.current = newOutput; onOutputChanged?.(newOutput); // update history @@ -406,11 +414,10 @@ const _Shell: ForwardRefRenderFunction = ( newHistory, redactInfo ? 'redact-sensitive-data' : 'keep-sensitive-data' ); + historyRef.current = newHistory; onHistoryChanged?.(newHistory); }, [ - output, - history, onOutputChanged, evaluate, redactInfo, @@ -450,16 +457,8 @@ const _Shell: ForwardRefRenderFunction = ( return Promise.resolve(false); }, [isOperationInProgress, runtime]); - const [isFirstRun, setIsFirstRun] = useState(true); - useEffect(() => { - if (!isFirstRun) { - return; - } - - setIsFirstRun(false); - - const evalLines = normalizeInitialEvaluate(initialEvaluate); + const evalLines = normalizeInitialEvaluate(initialEvaluateRef.current); if (evalLines.length) { void (async () => { for (const input of evalLines) { @@ -469,7 +468,7 @@ const _Shell: ForwardRefRenderFunction = ( } else { void updateShellPrompt(); } - }, [initialEvaluate, isFirstRun, onInput, updateShellPrompt]); + }, [onInput, updateShellPrompt]); useEffect(() => { rafraf(() => {