From 2be3d8909fb5b31d775f58976456dd2ede857f51 Mon Sep 17 00:00:00 2001 From: wirekang Date: Sun, 9 Jun 2024 23:35:26 +0900 Subject: [PATCH] fix #55 --- src/bootstrap.ts | 115 +++++++++++++-------------- src/controllers/editor-controller.ts | 11 ++- src/lib/utility/async-utils.ts | 46 +++++++++++ src/lib/utility/performance-utils.ts | 11 --- src/lib/utility/playground-utils.ts | 2 +- src/lib/utility/typescript-utils.ts | 4 - 6 files changed, 109 insertions(+), 80 deletions(-) create mode 100644 src/lib/utility/async-utils.ts delete mode 100644 src/lib/utility/performance-utils.ts diff --git a/src/bootstrap.ts b/src/bootstrap.ts index e8c029e..549c7bb 100644 --- a/src/bootstrap.ts +++ b/src/bootstrap.ts @@ -25,7 +25,7 @@ import { SettingsUtils } from "./lib/utility/settings-utils"; import { PanelContainerController } from "./controllers/panel-container-controller"; import { DomUtils } from "./lib/utility/dom-utils"; import { GtagUtils } from "./lib/utility/gtag-utils"; -import { PerformanceUtils } from "./lib/utility/performance-utils.js"; +import { AsyncUtils } from "./lib/utility/async-utils.js"; const lazy = null as unknown; const D = { @@ -117,7 +117,7 @@ async function setup() { setupQueryEditorController(); setupHotKeys(); setupMonaco(); - setupMoreController(); + await setupMoreController(); setupMobileModeController(); setLoading(false); setupOpenInNewTabController(); @@ -322,14 +322,10 @@ function toggleTypeEditor() { function setupTypeEditorController() { D.typeEditorController.setValue(D.state.editors.type); - // issue 45 - let timeout: any; - D.typeEditorController.onChange(() => { - clearTimeout(timeout); - timeout = setTimeout(() => { - D.queryEditorController.touch(); - }, PerformanceUtils.getDebounceTime()); + const debounce = AsyncUtils.makeDebounceTimeout(() => { + D.queryEditorController.touch(); }); + D.typeEditorController.onChange(debounce); } function setupQueryEditorController() { @@ -337,56 +333,59 @@ function setupQueryEditorController() { D.queryEditorController.setValue(header + D.state.editors.query); D.queryEditorController.setHiddenHeader(header); - D.queryEditorController.onChange(async (v) => { - D.resultController.clear(); - D.resultController.appendMessage("info", "Compiling..."); - const js = await TypescriptUtils.transpile(v); - D.resultController.clear(); - const outputs = await D.executer.execute(js); - if (outputs.length === 0) { - D.resultController.appendMessage("info", "Call kysely.execute()"); - } - if (outputs.filter((it) => it.type === "query").length > 1) { - D.resultController.appendMessage("info", "execute() has been called multiple times."); - D.resultController.appendPadding(); - } - logger.debug("execute outputs", outputs); - for (const output of outputs) { - switch (output.type) { - case "transaction": - D.resultController.appendMessage( - "trace", - `${StringUtils.capitalize(output.type2)}${StringUtils.capitalize(output.type)}`, - ); - break; - case "error": - D.resultController.appendMessage("error", `Error`); - D.resultController.appendCode("plaintext", output.message); - break; - case "query": - let sql = output.sql; - try { - const inlineParameters = SettingsUtils.get("sql-format:inline-parameters"); - const upperKeywords = SettingsUtils.get("sql-format:upper-keywords"); - sql = await D.formatter.formatSql(sql, output.parameters, { inlineParameters, upperKeywords }); - } catch (e) { - logger.error(e); - D.resultController.appendMessage("error", "Failed to format"); - } - D.resultController.appendCode("sql", sql); - if (output.parameters.length > 0) { - D.resultController.appendCode( - "plaintext", - output.parameters.map((p, i) => `[${i + 1}] ${p}`).join("\n"), + const eventQueue = AsyncUtils.makeEventQueue(); + D.queryEditorController.onChange((v) => { + eventQueue(async () => { + D.resultController.clear(); + D.resultController.appendMessage("info", "Loading..."); + const js = await TypescriptUtils.transpile(v); + const outputs = await D.executer.execute(js); + D.resultController.clear(); + if (outputs.length === 0) { + D.resultController.appendMessage("info", "Call kysely.execute()"); + } + if (outputs.filter((it) => it.type === "query").length > 1) { + D.resultController.appendMessage("info", "execute() has been called multiple times."); + D.resultController.appendPadding(); + } + logger.debug("execute outputs", outputs); + for (const output of outputs) { + switch (output.type) { + case "transaction": + D.resultController.appendMessage( + "trace", + `${StringUtils.capitalize(output.type2)}${StringUtils.capitalize(output.type)}`, ); - D.resultController.appendPadding(); - } - break; - case "log": - D.resultController.appendMessage("trace", `log: ${output.args.join(", ")}`); + break; + case "error": + D.resultController.appendMessage("error", `Error`); + D.resultController.appendCode("plaintext", output.message); + break; + case "query": + let sql = output.sql; + try { + const inlineParameters = SettingsUtils.get("sql-format:inline-parameters"); + const upperKeywords = SettingsUtils.get("sql-format:upper-keywords"); + sql = await D.formatter.formatSql(sql, output.parameters, { inlineParameters, upperKeywords }); + } catch (e) { + logger.error(e); + D.resultController.appendMessage("error", "Failed to format"); + } + D.resultController.appendCode("sql", sql); + if (output.parameters.length > 0) { + D.resultController.appendCode( + "plaintext", + output.parameters.map((p, i) => `[${i + 1}] ${p}`).join("\n"), + ); + D.resultController.appendPadding(); + } + break; + case "log": + D.resultController.appendMessage("trace", `log: ${output.args.join(", ")}`); + } } - } - D.hightlighter.highlight(); + D.hightlighter.highlight(); + }); }); } @@ -396,7 +395,7 @@ function executeQuery() { export async function bootstrap() { await init(); - setup(); + await setup(); } async function setupMonaco() { diff --git a/src/controllers/editor-controller.ts b/src/controllers/editor-controller.ts index c82797f..06ff4c9 100644 --- a/src/controllers/editor-controller.ts +++ b/src/controllers/editor-controller.ts @@ -3,7 +3,7 @@ import { CssUtils } from "../lib/utility/css-utils"; import { logger } from "../lib/utility/logger"; import { StringUtils } from "../lib/utility/string-utils"; import { DEBUG } from "../lib/constants"; -import { PerformanceUtils } from "../lib/utility/performance-utils.js"; +import { AsyncUtils } from "../lib/utility/async-utils.js"; export class EditorController { static async init( @@ -63,7 +63,6 @@ export class EditorController { return new EditorController(editor); } - private onChangeHandle?: any; private readonly onChangeListeners: Array<(v: string) => unknown> = []; private hiddenHeader?: string; @@ -74,11 +73,11 @@ export class EditorController { }); const model = this.editor.getModel()!; model.setEOL(monaco.editor.EndOfLineSequence.LF); + const debounce = AsyncUtils.makeDebounceTimeout(() => { + return this.invokeOnChange(); + }); model.onDidChangeContent((e) => { - clearTimeout(this.onChangeHandle); - this.onChangeHandle = setTimeout(() => { - this.invokeOnChange(); - }, PerformanceUtils.getDebounceTime()); + debounce(); }); }); } diff --git a/src/lib/utility/async-utils.ts b/src/lib/utility/async-utils.ts new file mode 100644 index 0000000..3a774fd --- /dev/null +++ b/src/lib/utility/async-utils.ts @@ -0,0 +1,46 @@ +import { DEBOUNCE_TIME, DEBOUNCE_TIME_LOWER } from "../constants.js"; +import { SettingsUtils } from "./settings-utils.js"; + +export class AsyncUtils { + private static getDebounceTime() { + if (SettingsUtils.get("editor:lower-debounce-time")) { + return DEBOUNCE_TIME_LOWER; + } + return DEBOUNCE_TIME; + } + + static makeDebounceTimeout(cb: () => unknown) { + let t: any = undefined; + const ms = AsyncUtils.getDebounceTime(); + return () => { + clearTimeout(t); + t = setTimeout(cb, ms); + }; + } + + static makeEventQueue() { + let running = false; + const queue: any[] = []; + const handle = async () => { + if (running) { + setTimeout(handle, 1); + return; + } + const e = queue.shift(); + if (!e) { + return; + } + try { + running = true; + await e(); + } finally { + running = false; + handle(); + } + }; + return (cb: () => Promise) => { + queue.push(cb); + handle(); + }; + } +} diff --git a/src/lib/utility/performance-utils.ts b/src/lib/utility/performance-utils.ts deleted file mode 100644 index 42d7875..0000000 --- a/src/lib/utility/performance-utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { DEBOUNCE_TIME, DEBOUNCE_TIME_LOWER } from "../constants.js"; -import { SettingsUtils } from "./settings-utils.js"; - -export class PerformanceUtils { - static getDebounceTime() { - if (SettingsUtils.get("editor:lower-debounce-time")) { - return DEBOUNCE_TIME_LOWER; - } - return DEBOUNCE_TIME; - } -} diff --git a/src/lib/utility/playground-utils.ts b/src/lib/utility/playground-utils.ts index 23a1ea5..7723aa8 100644 --- a/src/lib/utility/playground-utils.ts +++ b/src/lib/utility/playground-utils.ts @@ -2,7 +2,7 @@ import { DIALECT_CONSTRUCTORS, QUERY_EDITOR_HEADER_DELIMITER } from "../constant export class PlaygroundUtils { static getEntrypointUrl() { - return window.origin + "/playground.js"; + return window.origin + `/playground.js`; } static makeQueryEditorHeader(dialect: string) { diff --git a/src/lib/utility/typescript-utils.ts b/src/lib/utility/typescript-utils.ts index 4c32bb7..23e320d 100644 --- a/src/lib/utility/typescript-utils.ts +++ b/src/lib/utility/typescript-utils.ts @@ -12,8 +12,4 @@ export class TypescriptUtils { module: ts.ModuleKind.ES2020, }); } - - static async getVersion(): Promise { - return (await import("typescript")).version; - } }