diff --git a/backend/src/server.py b/backend/src/server.py
index 4485ee300..bbe550d39 100644
--- a/backend/src/server.py
+++ b/backend/src/server.py
@@ -432,7 +432,17 @@ async def get_dependencies(_request: Request):
await nodes_available()
all_dependencies = []
for package in api.registry.packages.values():
- pkg_dependencies = [x.toDict() for x in package.dependencies]
+ pkg_dependencies = []
+ for pkg_dep in package.dependencies:
+ installed_version = installed_packages.get(pkg_dep.pypi_name, None)
+ pkg_dep_item = {
+ **pkg_dep.toDict(),
+ }
+ if installed_version is None:
+ pkg_dep_item["installed"] = None
+ else:
+ pkg_dep_item["installed"] = installed_version
+ pkg_dependencies.append(pkg_dep_item)
if package.name == "chaiNNer_standard":
continue
else:
diff --git a/src/common/dependencies.ts b/src/common/dependencies.ts
index 311630bf7..39818312c 100644
--- a/src/common/dependencies.ts
+++ b/src/common/dependencies.ts
@@ -10,6 +10,7 @@ export interface PyPiPackage {
*/
sizeEstimate: number;
autoUpdate: boolean;
+ installed: Version | null;
}
export interface Package {
name: string;
diff --git a/src/renderer/contexts/DependencyContext.tsx b/src/renderer/contexts/DependencyContext.tsx
index 675ba7562..a8e0b3448 100644
--- a/src/renderer/contexts/DependencyContext.tsx
+++ b/src/renderer/contexts/DependencyContext.tsx
@@ -32,12 +32,13 @@ import {
} from '@chakra-ui/react';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { BsQuestionCircle, BsTerminalFill } from 'react-icons/bs';
+import { useQuery } from 'react-query';
import { createContext, useContext } from 'use-context-selector';
import { Version } from '../../common/common-types';
import { Package, PyPiPackage } from '../../common/dependencies';
import { Integration, externalIntegrations } from '../../common/externalIntegrations';
import { log } from '../../common/log';
-import { OnStdio, PipList, runPipInstall, runPipList, runPipUninstall } from '../../common/pip';
+import { OnStdio, runPipInstall, runPipUninstall } from '../../common/pip';
import { noop } from '../../common/util';
import { versionGt } from '../../common/version';
import { useAsyncEffect } from '../hooks/useAsyncEffect';
@@ -76,7 +77,7 @@ const formatSizeEstimate = (packages: readonly PyPiPackage[]): string =>
formatBytes(packages.reduce((a, p) => a + p.sizeEstimate, 0));
const FeaturePackage = memo(
- ({ pkg, installedVersion }: { pkg: PyPiPackage; installedVersion?: Version }) => {
+ ({ pkg, installedVersion }: { pkg: PyPiPackage; installedVersion: Version | null }) => {
let color = 'red.500';
let tagText = 'Missing';
let versionString: string = pkg.version;
@@ -115,7 +116,6 @@ const FeaturePackage = memo(
const Feature = memo(
({
dep,
- pipList,
isRunningShell,
progress,
onInstall,
@@ -123,17 +123,15 @@ const Feature = memo(
onUpdate,
}: {
dep: Package;
- pipList: PipList;
isRunningShell: boolean;
progress?: number;
onInstall: () => void;
onUninstall: () => void;
onUpdate: () => void;
}) => {
- const missingPackages = dep.dependencies.filter((p) => !pipList[p.pypiName]);
- const outdatedPackages = dep.dependencies.filter((p) => {
- const installedVersion = pipList[p.pypiName];
- return installedVersion && versionGt(p.version, installedVersion);
+ const missingPackages = dep.dependencies.filter((d) => !d.installed);
+ const outdatedPackages = dep.dependencies.filter((d) => {
+ return d.installed && versionGt(d.version, d.installed);
});
return (
@@ -255,11 +253,11 @@ const Feature = memo(
key={dep.name}
w="full"
>
- {dep.dependencies.map((p) => (
+ {dep.dependencies.map((d) => (
))}
@@ -279,20 +277,9 @@ export const DependencyProvider = memo(({ children }: React.PropsWithChildren();
- const refreshInstalledPackages = useCallback(() => setPipList(undefined), [setPipList]);
-
const [isConsoleOpen, setIsConsoleOpen] = useState(false);
const [usePipDirectly, setUsePipDirectly] = useState(false);
- useAsyncEffect(() => {
- if (pipList) return;
- return {
- supplier: () => runPipList(pythonInfo),
- successEffect: setPipList,
- };
- }, [pythonInfo, pipList, setPipList]);
-
const [hasNvidia, setHasNvidia] = useState(false);
useAsyncEffect(
() => ({
@@ -302,17 +289,22 @@ export const DependencyProvider = memo(({ children }: React.PropsWithChildren([]);
- useAsyncEffect(
- () => ({
- supplier: async () => {
- const res = await backend.dependencies();
- return res.filter((d) => d.dependencies.length > 0);
- },
- successEffect: setAvailableDeps,
- }),
- [backend]
- );
+ const { data: depList, refetch } = useQuery({
+ queryKey: 'dependencies',
+ queryFn: async () => {
+ try {
+ const response = await backend.dependencies();
+ return response.filter((d) => d.dependencies.length > 0);
+ } catch (error) {
+ log.error(error);
+ throw error;
+ }
+ },
+ cacheTime: 0,
+ retry: 25,
+ refetchOnWindowFocus: false,
+ refetchInterval: false,
+ });
const [installingPackage, setInstallingPackage] = useState(null);
const [uninstallingPackage, setUninstallingPackage] = useState(null);
@@ -341,12 +333,20 @@ export const DependencyProvider = memo(({ children }: React.PropsWithChildren {
- setIsRunningShell(false);
- refreshInstalledPackages();
- setInstallingPackage(null);
- setUninstallingPackage(null);
- setProgress(0);
- restart().catch(log.error);
+ restart()
+ .catch(log.error)
+ .then(() => {
+ refetch()
+ .catch(log.error)
+ .then(() => {
+ setIsRunningShell(false);
+ setInstallingPackage(null);
+ setUninstallingPackage(null);
+ setProgress(0);
+ })
+ .catch(log.error);
+ })
+ .catch(log.error);
});
};
@@ -372,22 +372,20 @@ export const DependencyProvider = memo(({ children }: React.PropsWithChildren {
- return availableDeps.filter(({ dependencies }) =>
- dependencies.some(({ pypiName, version }) => {
- if (!pipList) {
- return false;
- }
- const installedVersion = pipList[pypiName];
- if (!installedVersion) {
- return true;
- }
- return versionGt(version, installedVersion);
- })
- ).length;
- }, [pipList, availableDeps]);
+ return (
+ depList?.filter(({ dependencies }) =>
+ dependencies.some(({ version, installed }) => {
+ if (!installed) {
+ return true;
+ }
+ return versionGt(version, installed);
+ })
+ ).length ?? 0
+ );
+ }, [depList]);
const value = useMemoObject({
openDependencyManager: onOpen,
@@ -496,7 +494,7 @@ export const DependencyProvider = memo(({ children }: React.PropsWithChildren
- {!pipList ? (
+ {!depList ? (
) : (
- {availableDeps.map((dep) => {
+ {depList.map((dep) => {
const install = () => installPackage(dep);
const uninstall = () => {
showAlert({
@@ -540,7 +538,6 @@ export const DependencyProvider = memo(({ children }: React.PropsWithChildren