From c2cb20334d1b40077e482ce9e447813f2cd3ef25 Mon Sep 17 00:00:00 2001 From: Asraye Date: Fri, 21 Nov 2025 03:34:28 +1100 Subject: [PATCH] refactor: improve consistency and cache --- src/common/createPreloader.ts | 59 ++++++++++++----------------------- 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/src/common/createPreloader.ts b/src/common/createPreloader.ts index 32305874..f8ed230c 100644 --- a/src/common/createPreloader.ts +++ b/src/common/createPreloader.ts @@ -5,52 +5,33 @@ export function createPreloader( fun: (...args: U) => Promise ) { let timeout: undefined | NodeJS.Timeout; - let waiting: ((value: T | PromiseLike) => void)[] = []; - let argsStr: string | null = null; - let data: T | null = null; - let dataSavedAt: number | null = null; - - const preload = (...args: U) => { - if (timeout) { - clearTimeout(timeout); - } - timeout = setTimeout(() => { - run(...args); - }, 200); - }; + const cache = new Map(); + const activeRequest = new Map(); const run = (...args: U) => { - const newArgsStr = JSON.stringify(args); - - if (argsStr !== newArgsStr) { - waiting = []; - argsStr = newArgsStr; - data = null; + const key = JSON.stringify(args); + const now = Date.now(); + const cached = cache.get(key); + if (cached && now - cached.savedAt < 10000) { + return Promise.resolve(cached.data); } - return new Promise((resolve) => { - if (data && argsStr === newArgsStr) { - if (Date.now() - dataSavedAt! < 10000) { - resolve(data); - return; - } - data = null; - } - if (waiting.length) { - waiting.push(resolve); - return; - } - waiting.push(resolve); + const token = (activeRequest.get(key) || 0) + 1; + activeRequest.set(key, token); - fun(...args).then((newData) => { - data = newData; - dataSavedAt = Date.now(); - if (argsStr !== newArgsStr) return; - waiting.forEach((resolve) => resolve(newData)); - waiting = []; - }); + return fun(...args).then((result) => { + if (activeRequest.get(key) === token) { + cache.set(key, { data: result, savedAt: Date.now() }); + } + return result; }); }; + + const preload = (...args: U) => { + if (timeout) clearTimeout(timeout); + timeout = setTimeout(() => run(...args), 200); + }; + return { run, preload }; }