Batch extension version checks

3c82d961bdf364a9591366e6eddc4746ae8f275b

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

1 files changed, +28 -9Ignore whitespace
public/scripts/extensions.js+28 -9
@@ -586,7 +586,6 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal,
586 const isUserAdmin = isAdmin();586 const isUserAdmin = isAdmin();
587 const extensionIcon = getExtensionIcon();587 const extensionIcon = getExtensionIcon();
588 const displayName = manifest.display_name;588 const displayName = manifest.display_name;
589 let displayVersion = manifest.version ? ` v${manifest.version}` : '';
590 const externalId = name.replace('third-party', '');589 const externalId = name.replace('third-party', '');
591 let originHtml = '';590 let originHtml = '';
592 if (isExternal) {591 if (isExternal) {
@@ -632,7 +631,7 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal,
632 ${originHtml}631 ${originHtml}
633 <span class="${isActive ? 'extension_enabled' : isDisabled ? 'extension_disabled' : 'extension_missing'}">632 <span class="${isActive ? 'extension_enabled' : isDisabled ? 'extension_disabled' : 'extension_missing'}">
634 <span class="extension_name">${DOMPurify.sanitize(displayName)}</span>633 <span class="extension_name">${DOMPurify.sanitize(displayName)}</span>
635 <span class="extension_version">${displayVersion}</span>634 <span class="extension_version"></span>
636 ${modulesInfo}635 ${modulesInfo}
637 </span>636 </span>
638 ${isExternal ? '</a>' : ''}637 ${isExternal ? '</a>' : ''}
@@ -1032,6 +1031,29 @@ export function doDailyExtensionUpdatesCheck() {
1032 }, 1);1031 }, 1);
1033}1032}
10341033
1034const concurrencyLimit = 5;
1035let activeRequestsCount = 0;
1036const versionCheckQueue = [];
1037
1038function enqueueVersionCheck(fn) {
1039 return new Promise((resolve, reject) => {
1040 versionCheckQueue.push(() => fn().then(resolve).catch(reject));
1041 processVersionCheckQueue();
1042 });
1043}
1044
1045function 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
1035/**1057/**
1036 * Performs a manual check for updates on all 3rd-party extensions.1058 * Performs a manual check for updates on all 3rd-party extensions.
1037 * @param {AbortSignal} abortSignal Signal to abort the operation1059 * @param {AbortSignal} abortSignal Signal to abort the operation
@@ -1041,7 +1063,7 @@ async function checkForUpdatesManual(abortSignal) {
1041 const promises = [];1063 const promises = [];
1042 for (const id of Object.keys(manifests).filter(x => x.startsWith('third-party'))) {1064 for (const id of Object.keys(manifests).filter(x => x.startsWith('third-party'))) {
1043 const externalId = id.replace('third-party', '');1065 const externalId = id.replace('third-party', '');
1044 const promise = new Promise(async (resolve, reject) => {1066 const promise = enqueueVersionCheck(async () => {
1045 try {1067 try {
1046 const data = await getExtensionVersion(externalId, abortSignal);1068 const data = await getExtensionVersion(externalId, abortSignal);
1047 const extensionBlock = document.querySelector(`.extension_block[data-name="${externalId}"]`);1069 const extensionBlock = document.querySelector(`.extension_block[data-name="${externalId}"]`);
@@ -1072,10 +1094,8 @@ async function checkForUpdatesManual(abortSignal) {
1072 versionElement.textContent += ` (${branch}-${commitHash.substring(0, 7)})`;1094 versionElement.textContent += ` (${branch}-${commitHash.substring(0, 7)})`;
1073 }1095 }
1074 }1096 }
1075 resolve();
1076 } catch (error) {1097 } catch (error) {
1077 console.error('Error checking for extension updates', error);1098 console.error('Error checking for extension updates', error);
1078 reject();
1079 }1099 }
1080 });1100 });
1081 promises.push(promise);1101 promises.push(promise);
@@ -1111,17 +1131,16 @@ async function checkForExtensionUpdates(force) {
1111 console.debug(`Skipping global extension: ${manifest.display_name} (${id}) for non-admin user`);1131 console.debug(`Skipping global extension: ${manifest.display_name} (${id}) for non-admin user`);
1112 continue;1132 continue;
1113 }1133 }
1134
1114 if (manifest.auto_update && id.startsWith('third-party')) {1135 if (manifest.auto_update && id.startsWith('third-party')) {
1115 const promise = new Promise(async (resolve, reject) => {1136 const promise = enqueueVersionCheck(async () => {
1116 try {1137 try {
1117 const data = await getExtensionVersion(id.replace('third-party', ''));1138 const data = await getExtensionVersion(id.replace('third-party', ''));
1118 if (data.isUpToDate === false) {1139 if (!data.isUpToDate) {
1119 updatesAvailable.push(manifest.display_name);1140 updatesAvailable.push(manifest.display_name);
1120 }1141 }
1121 resolve();
1122 } catch (error) {1142 } catch (error) {
1123 console.error('Error checking for extension updates', error);1143 console.error('Error checking for extension updates', error);
1124 reject();
1125 }1144 }
1126 });1145 });
1127 promises.push(promise);1146 promises.push(promise);