-
Hi, I’m encountering an issue while trying to handle updates from an external callback using Inquirer’s hook-based system. I’m building a custom prompt where config.refresh is used to listen for updates, and I want to debounce the updates to avoid excessive rerenders. However, I’m running into the following error:
Here’s my implementation: import { createPrompt, useEffect, useKeypress, useMemo, useState } from '@inquirer/core';
import { isExitKey } from './tools';
import type { CliErrors, CliErrorsBuild } from '../../server/Connection';
import { DiagnosticSeverity } from 'vscode-languageserver';
export type LogConfig = {
errors: CliErrors;
refresh: (cb: (errors: CliErrorsBuild, build: string) => void) => void;
stopRefresh: (cb: (errors: CliErrorsBuild, build: string) => void) => void;
};
export default createPrompt<void, LogConfig>((config, done) => {
let baseError = config.errors[''] ?? {};
const [errors, setErrors] = useState<CliErrorsBuild>({ ...baseError });
useEffect(() => {
let delayTimeout: NodeJS.Timeout;
const refresh = (newErrors: CliErrorsBuild, newBuild: string) => {
clearTimeout(delayTimeout);
delayTimeout = setTimeout(() => {
setErrors({ ...newErrors });
}, 300);
};
config.refresh(refresh);
return () => {
clearTimeout(delayTimeout);
config.stopRefresh(refresh);
};
}, [config]);
const renderTxt = useMemo(() => {
const errorsTxt: string[] = [];
const errorsTemp: CliErrorsBuild = errors;
for (let uri in errorsTemp) {
for (let diagnostic of errorsTemp[uri]) {
let sev = '';
switch (diagnostic.severity) {
case DiagnosticSeverity.Error:
sev = '\x1b[31m[error]\x1b[0m';
break;
case DiagnosticSeverity.Warning:
sev = '\x1b[33m[warning]\x1b[0m';
break;
case DiagnosticSeverity.Information:
sev = '\x1b[34m[info]\x1b[0m';
break;
case DiagnosticSeverity.Hint:
sev = '\x1b[90m[hint]\x1b[0m';
continue;
}
errorsTxt.push(`${uri}:${diagnostic.range.start.line + 1} - ${sev} : ${diagnostic.message}`);
}
}
if (errorsTxt.length === 0) {
return 'No error';
}
return errorsTxt.join('\r\n');
}, [errors]);
useKeypress(async (key, rl) => {
if (isExitKey(key)) {
done();
}
});
return renderTxt;
}); I’m unsure how to handle updates from an external callback like config.refresh + debounce to avoid blink? Any guidance or suggestions would be greatly appreciated. Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
I think the setTimeout might trigger even though you clear it (if it's already in queue on the event queue). I'd set a local variable to skip the call of cancel runs first. |
Beta Was this translation helpful? Give feedback.
Hum, then it could be because the async context is lost when giving a callback somewhere.
Try adding some
AsyncResource.bind(() => { ... })
; like onsetTimeout
: