mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-30 20:43: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
|
||||
let storeFilteredList = [];
|
||||
|
||||
function storeCacheExpired() {
|
||||
return !cacheTimestamp || (Date.now() - cacheTimestamp >= CACHE_DURATION);
|
||||
}
|
||||
|
||||
// ── Plugin Store Filter State ───────────────────────────────────────────
|
||||
const storeFilterState = {
|
||||
sort: safeLocalStorage.getItem('storeSort') || 'a-z',
|
||||
@@ -1214,12 +1218,13 @@ function initializePlugins() {
|
||||
}
|
||||
|
||||
// Load both installed plugins and plugin store.
|
||||
// On HTMX re-swaps use cached store data (fetchCommitInfo=false) to avoid
|
||||
// re-hitting GitHub on every tab switch; only fetch fresh on first load.
|
||||
const isReswap = !!window.pluginManager._reswap;
|
||||
// On HTMX re-swaps with a still-warm cache, skip GitHub metadata to avoid
|
||||
// re-hitting the API on every tab switch. If the cache TTL has expired even
|
||||
// during a re-swap, fetch fresh data including GitHub commit/version info.
|
||||
const isReswapWarm = !!window.pluginManager._reswap && !storeCacheExpired();
|
||||
window.pluginManager._reswap = false;
|
||||
loadInstalledPlugins();
|
||||
searchPluginStore(!isReswap);
|
||||
searchPluginStore(!isReswapWarm);
|
||||
|
||||
// Setup search functionality (with guard against duplicate listeners)
|
||||
const searchInput = document.getElementById('plugin-search');
|
||||
@@ -5133,10 +5138,13 @@ function refreshPlugins() {
|
||||
pluginStoreCache = null;
|
||||
cacheTimestamp = null;
|
||||
|
||||
refreshInstalledPlugins(); // invalidates cache before fetching
|
||||
// Fetch latest metadata from GitHub when refreshing
|
||||
// refreshInstalledPlugins() is async (returns a Promise via loadInstalledPlugins).
|
||||
// Only search the store and notify after window.installedPlugins is updated so
|
||||
// that Installed/Reinstall badges reflect the freshly fetched state.
|
||||
refreshInstalledPlugins().then(() => {
|
||||
searchPluginStore(true);
|
||||
showNotification('Plugins refreshed with latest metadata from GitHub', 'success');
|
||||
});
|
||||
}
|
||||
|
||||
function restartDisplay() {
|
||||
|
||||
Reference in New Issue
Block a user