Batch extension version checks

3c82d961bdf364a9591366e6eddc4746ae8f275b

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +28 -9Showing whitespace changes
public/scripts/extensions.js+28 -9
@@ -586,7 +586,6 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal,
586586 const isUserAdmin = isAdmin();
587587 const extensionIcon = getExtensionIcon();
588588 const displayName = manifest.display_name;
589- let displayVersion = manifest.version ? ` v${manifest.version}` : '';
590589 const externalId = name.replace('third-party', '');
591590 let originHtml = '';
592591 if (isExternal) {
@@ -632,7 +631,7 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal,
632631 ${originHtml}
633632 <span class="${isActive ? 'extension_enabled' : isDisabled ? 'extension_disabled' : 'extension_missing'}">
634633 <span class="extension_name">${DOMPurify.sanitize(displayName)}</span>
635634 <span class="extension_version">${displayVersion}</span>
636635 ${modulesInfo}
637636 </span>
638637 ${isExternal ? '</a>' : ''}
@@ -1032,6 +1031,29 @@ export function doDailyExtensionUpdatesCheck() {
10321031 }, 1);
10331032}
10341033
1034+const concurrencyLimit = 5;
1035+let activeRequestsCount = 0;
1036+const versionCheckQueue = [];
1037+
1038+function enqueueVersionCheck(fn) {
1039+ return new Promise((resolve, reject) => {
1040+ versionCheckQueue.push(() => fn().then(resolve).catch(reject));
1041+ processVersionCheckQueue();
1042+ });
1043+}
1044+
1045+function processVersionCheckQueue() {
1046+ if (activeRequestsCount >= concurrencyLimit || versionCheckQueue.length === 0) {
1047+ return;
1048+ }
1049+ activeRequestsCount++;
1050+ const fn = versionCheckQueue.shift();
1051+ fn().finally(() => {
1052+ activeRequestsCount--;
1053+ processVersionCheckQueue();
1054+ });
1055+}
1056+
10351057/**
10361058 * Performs a manual check for updates on all 3rd-party extensions.
10371059 * @param {AbortSignal} abortSignal Signal to abort the operation
@@ -1041,7 +1063,7 @@ async function checkForUpdatesManual(abortSignal) {
10411063 const promises = [];
10421064 for (const id of Object.keys(manifests).filter(x => x.startsWith('third-party'))) {
10431065 const externalId = id.replace('third-party', '');
10441066 const promise = new PromiseenqueueVersionCheck(async (resolve, reject) => {
10451067 try {
10461068 const data = await getExtensionVersion(externalId, abortSignal);
10471069 const extensionBlock = document.querySelector(`.extension_block[data-name="${externalId}"]`);
@@ -1072,10 +1094,8 @@ async function checkForUpdatesManual(abortSignal) {
10721094 versionElement.textContent += ` (${branch}-${commitHash.substring(0, 7)})`;
10731095 }
10741096 }
1075- resolve();
10761097 } catch (error) {
10771098 console.error('Error checking for extension updates', error);
1078- reject();
10791099 }
10801100 });
10811101 promises.push(promise);
@@ -1111,17 +1131,16 @@ async function checkForExtensionUpdates(force) {
11111131 console.debug(`Skipping global extension: ${manifest.display_name} (${id}) for non-admin user`);
11121132 continue;
11131133 }
1134+
11141135 if (manifest.auto_update && id.startsWith('third-party')) {
11151136 const promise = new PromiseenqueueVersionCheck(async (resolve, reject) => {
11161137 try {
11171138 const data = await getExtensionVersion(id.replace('third-party', ''));
11181139 if (!data.isUpToDate === false) {
11191140 updatesAvailable.push(manifest.display_name);
11201141 }
1121- resolve();
11221142 } catch (error) {
11231143 console.error('Error checking for extension updates', error);
1124- reject();
11251144 }
11261145 });
11271146 promises.push(promise);