(states?: MarketplaceState[])
| 182 | |
| 183 | // Apply all pending changes |
| 184 | const applyChanges = async (states?: MarketplaceState[]) => { |
| 185 | const statesToProcess = states || marketplaceStates; |
| 186 | const wasInDetailsView = internalView === 'details'; |
| 187 | setIsProcessing(true); |
| 188 | setProcessError(null); |
| 189 | setSuccessMessage(null); |
| 190 | setProgressMessage(null); |
| 191 | try { |
| 192 | const settings = getSettingsForSource('userSettings'); |
| 193 | let updatedCount = 0; |
| 194 | let removedCount = 0; |
| 195 | const refreshedMarketplaces = new Set<string>(); |
| 196 | for (const state of statesToProcess) { |
| 197 | // Handle remove |
| 198 | if (state.pendingRemove) { |
| 199 | // First uninstall all plugins from this marketplace |
| 200 | if (state.installedPlugins && state.installedPlugins.length > 0) { |
| 201 | const newEnabledPlugins = { |
| 202 | ...settings?.enabledPlugins |
| 203 | }; |
| 204 | for (const plugin of state.installedPlugins) { |
| 205 | const pluginId = createPluginId(plugin.name, state.name); |
| 206 | // Mark as disabled/uninstalled |
| 207 | newEnabledPlugins[pluginId] = false; |
| 208 | } |
| 209 | updateSettingsForSource('userSettings', { |
| 210 | enabledPlugins: newEnabledPlugins |
| 211 | }); |
| 212 | } |
| 213 | |
| 214 | // Then remove the marketplace |
| 215 | await removeMarketplaceSource(state.name); |
| 216 | removedCount++; |
| 217 | logEvent('tengu_marketplace_removed', { |
| 218 | marketplace_name: state.name as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 219 | plugins_uninstalled: state.installedPlugins?.length || 0 |
| 220 | }); |
| 221 | continue; |
| 222 | } |
| 223 | |
| 224 | // Handle update |
| 225 | if (state.pendingUpdate) { |
| 226 | // Refresh individual marketplace for efficiency with progress reporting |
| 227 | await refreshMarketplace(state.name, (message: string) => { |
| 228 | setProgressMessage(message); |
| 229 | }); |
| 230 | updatedCount++; |
| 231 | refreshedMarketplaces.add(state.name.toLowerCase()); |
| 232 | logEvent('tengu_marketplace_updated', { |
| 233 | marketplace_name: state.name as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS |
| 234 | }); |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | // After marketplace clones are refreshed, bump installed plugins from |
| 239 | // those marketplaces to the new version. Without this, the loader's |
| 240 | // cache-on-miss (copyPluginToVersionedCache) creates the new version |
| 241 | // dir on the next loadAllPlugins() call, but installed_plugins.json |
no test coverage detected