From 35da8a00f385c5a2b9e76e4a071c8e63d4129c9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Vidra?= Date: Sat, 2 Mar 2024 14:34:01 +0100 Subject: [PATCH] feat: make polling interval longer (#38) * feat: make polling interval longer * feat: throttle document change * fix: waiting for element --- .../tests/tooltip-error/tooltip-error.spec.ts | 1 + workspaces/js/src/core/document-change.ts | 5 ++++- workspaces/js/src/core/flow-state.ts | 4 ++-- workspaces/js/src/core/init.ts | 2 +- workspaces/js/src/core/render.tsx | 4 ++-- workspaces/js/src/lib/throttle.ts | 17 +++++++++++++++++ 6 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 workspaces/js/src/lib/throttle.ts diff --git a/workspaces/e2e/tests/tooltip-error/tooltip-error.spec.ts b/workspaces/e2e/tests/tooltip-error/tooltip-error.spec.ts index fdf0a3a..88ac2c6 100644 --- a/workspaces/e2e/tests/tooltip-error/tooltip-error.spec.ts +++ b/workspaces/e2e/tests/tooltip-error/tooltip-error.spec.ts @@ -12,6 +12,7 @@ test("should not emit any error event if it gets invalidates quickly", async ({ await page.locator(".start-flow").click(); await expect(page.locator("[data-type='tooltipError']")).toHaveCount(0); await page.locator(".add-target").click(); + await expect(page.locator(".flows-tooltip")).toBeVisible(); await page.locator(".remove-target").click(); await page.locator(".add-target").click(); await expect(page.locator("[data-type='tooltipError']")).toHaveCount(0); diff --git a/workspaces/js/src/core/document-change.ts b/workspaces/js/src/core/document-change.ts index a51ce19..f1d9e93 100644 --- a/workspaces/js/src/core/document-change.ts +++ b/workspaces/js/src/core/document-change.ts @@ -1,6 +1,7 @@ +import { throttle } from "../lib/throttle"; import { FlowsContext } from "./flows-context"; -export const handleDocumentChange = (): void => { +const _handleDocumentChange = (): void => { FlowsContext.getInstance().instances.forEach((state) => { if (state.waitingForElement) return state.render(); @@ -12,3 +13,5 @@ export const handleDocumentChange = (): void => { } }); }; + +export const handleDocumentChange = throttle(_handleDocumentChange, 250); diff --git a/workspaces/js/src/core/flow-state.ts b/workspaces/js/src/core/flow-state.ts index eb0097f..69ed80a 100644 --- a/workspaces/js/src/core/flow-state.ts +++ b/workspaces/js/src/core/flow-state.ts @@ -86,7 +86,7 @@ export class FlowState { type: "tooltipError", targetElement: step.targetElement, }); - }, 1000); + }, 2000); const isFork = Array.isArray(step); if (isFork) { @@ -217,8 +217,8 @@ export class FlowState { * Remove the flow element from the DOM. Used before rendering next step and when flow is finished. */ unmount(): this { - if (!this.flowElement) return this; this.waitingForElement = false; + if (!this.flowElement) return this; this.flowElement.cleanup?.(); this.flowElement.element.remove(); return this; diff --git a/workspaces/js/src/core/init.ts b/workspaces/js/src/core/init.ts index bb3e124..eff91c1 100644 --- a/workspaces/js/src/core/init.ts +++ b/workspaces/js/src/core/init.ts @@ -166,7 +166,7 @@ const _init = (options: FlowsInitOptions): void => { if (locationChangeInterval !== null) clearInterval(locationChangeInterval); locationChangeInterval = window.setInterval(() => { handleLocationChange(); - }, 50); + }, 250); addHandlers([ { type: "click", handler: handleClick }, diff --git a/workspaces/js/src/core/render.tsx b/workspaces/js/src/core/render.tsx index 0781394..07f81ad 100644 --- a/workspaces/js/src/core/render.tsx +++ b/workspaces/js/src/core/render.tsx @@ -290,11 +290,11 @@ const getBoundaryEl = (state: FlowState): Element | undefined => { }; export const render = (state: FlowState): void => { + state.unmount(); + const step = state.currentStep; if (!step) return; - state.unmount(); - if (isTooltipStep(step)) { const target = document.querySelector(step.targetElement); if (target) { diff --git a/workspaces/js/src/lib/throttle.ts b/workspaces/js/src/lib/throttle.ts new file mode 100644 index 0000000..71ad20a --- /dev/null +++ b/workspaces/js/src/lib/throttle.ts @@ -0,0 +1,17 @@ +/* eslint-disable @typescript-eslint/no-explicit-any -- handy in this file */ + +export const throttle = any>( + fn: T, + delay: number, +): ((...args: Parameters) => void) => { + let timerFlag: number | null = null; + + return (...args) => { + if (timerFlag === null) { + timerFlag = window.setTimeout(() => { + timerFlag = null; + fn(...args); + }, delay); + } + }; +};