mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-05-01 04:53:00 +00:00
fix(plugins): fix async race in refreshPlugins; use cache TTL to gate re-swap metadata fetch
refreshPlugins() called searchPluginStore(true) and showNotification() immediately after refreshInstalledPlugins() without awaiting the returned Promise, so window.installedPlugins could still be stale when the store rendered its Installed/Reinstall badges. Chain .then() so both run only after the fetch completes. In initializePlugins(), the re-swap path always passed fetchCommitInfo=false to searchPluginStore, skipping GitHub metadata even when the 5-minute cache TTL had expired. Add storeCacheExpired() helper and compute isReswapWarm = _reswap && !storeCacheExpired() so fresh metadata is fetched whenever the cache is cold, regardless of whether the render is a first load or a tab re-swap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -898,6 +898,10 @@ window.currentPluginConfig = null;
|
|||||||
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
|
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
|
||||||
let storeFilteredList = [];
|
let storeFilteredList = [];
|
||||||
|
|
||||||
|
function storeCacheExpired() {
|
||||||
|
return !cacheTimestamp || (Date.now() - cacheTimestamp >= CACHE_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
// ── Plugin Store Filter State ───────────────────────────────────────────
|
// ── Plugin Store Filter State ───────────────────────────────────────────
|
||||||
const storeFilterState = {
|
const storeFilterState = {
|
||||||
sort: safeLocalStorage.getItem('storeSort') || 'a-z',
|
sort: safeLocalStorage.getItem('storeSort') || 'a-z',
|
||||||
@@ -1214,12 +1218,13 @@ function initializePlugins() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load both installed plugins and plugin store.
|
// Load both installed plugins and plugin store.
|
||||||
// On HTMX re-swaps use cached store data (fetchCommitInfo=false) to avoid
|
// On HTMX re-swaps with a still-warm cache, skip GitHub metadata to avoid
|
||||||
// re-hitting GitHub on every tab switch; only fetch fresh on first load.
|
// re-hitting the API on every tab switch. If the cache TTL has expired even
|
||||||
const isReswap = !!window.pluginManager._reswap;
|
// during a re-swap, fetch fresh data including GitHub commit/version info.
|
||||||
|
const isReswapWarm = !!window.pluginManager._reswap && !storeCacheExpired();
|
||||||
window.pluginManager._reswap = false;
|
window.pluginManager._reswap = false;
|
||||||
loadInstalledPlugins();
|
loadInstalledPlugins();
|
||||||
searchPluginStore(!isReswap);
|
searchPluginStore(!isReswapWarm);
|
||||||
|
|
||||||
// Setup search functionality (with guard against duplicate listeners)
|
// Setup search functionality (with guard against duplicate listeners)
|
||||||
const searchInput = document.getElementById('plugin-search');
|
const searchInput = document.getElementById('plugin-search');
|
||||||
@@ -5133,10 +5138,13 @@ function refreshPlugins() {
|
|||||||
pluginStoreCache = null;
|
pluginStoreCache = null;
|
||||||
cacheTimestamp = null;
|
cacheTimestamp = null;
|
||||||
|
|
||||||
refreshInstalledPlugins(); // invalidates cache before fetching
|
// refreshInstalledPlugins() is async (returns a Promise via loadInstalledPlugins).
|
||||||
// Fetch latest metadata from GitHub when refreshing
|
// Only search the store and notify after window.installedPlugins is updated so
|
||||||
searchPluginStore(true);
|
// that Installed/Reinstall badges reflect the freshly fetched state.
|
||||||
showNotification('Plugins refreshed with latest metadata from GitHub', 'success');
|
refreshInstalledPlugins().then(() => {
|
||||||
|
searchPluginStore(true);
|
||||||
|
showNotification('Plugins refreshed with latest metadata from GitHub', 'success');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function restartDisplay() {
|
function restartDisplay() {
|
||||||
|
|||||||
Reference in New Issue
Block a user