mirror of
https://github.com/ivabus/gui
synced 2025-04-23 14:07:14 +03:00
watch directory for newly installed packages (#624)
This commit is contained in:
parent
6f4725d21c
commit
ec166132c8
9 changed files with 163 additions and 126 deletions
|
@ -1,5 +1,12 @@
|
||||||
import { ipcMain, app, BrowserWindow } from "electron";
|
import { ipcMain, app, BrowserWindow } from "electron";
|
||||||
import { deletePackageFolder, getInstalledPackages, cacheImage } from "./tea-dir";
|
import {
|
||||||
|
deletePackageFolder,
|
||||||
|
getInstalledPackages,
|
||||||
|
getInstalledVersionsForPackage,
|
||||||
|
cacheImage,
|
||||||
|
startMonitoringTeaDir,
|
||||||
|
stopMonitoringTeaDir
|
||||||
|
} from "./tea-dir";
|
||||||
import { readSessionData, writeSessionData, pollAuth } from "./auth";
|
import { readSessionData, writeSessionData, pollAuth } from "./auth";
|
||||||
import type { Packages, Session } from "../../src/libs/types";
|
import type { Packages, Session } from "../../src/libs/types";
|
||||||
import log from "./logger";
|
import log from "./logger";
|
||||||
|
@ -37,6 +44,16 @@ export default function initializeHandlers({ notifyMainWindow }: HandlerOptions)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("get-installed-package-versions", async (_, fullName: string) => {
|
||||||
|
try {
|
||||||
|
log.info(`getting installed versions for package: ${fullName}`);
|
||||||
|
return await getInstalledVersionsForPackage(fullName);
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.handle("get-session", async () => {
|
ipcMain.handle("get-session", async () => {
|
||||||
try {
|
try {
|
||||||
log.info("getting session");
|
log.info("getting session");
|
||||||
|
@ -230,4 +247,22 @@ export default function initializeHandlers({ notifyMainWindow }: HandlerOptions)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("monitor-tea-dir", async () => {
|
||||||
|
try {
|
||||||
|
await startMonitoringTeaDir(notifyMainWindow);
|
||||||
|
} catch (err) {
|
||||||
|
log.error("Failed to monitor tea dir", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("stop-monitor-tea-dir", async () => {
|
||||||
|
try {
|
||||||
|
await stopMonitoringTeaDir();
|
||||||
|
} catch (err) {
|
||||||
|
log.error("Failed to stop monitoring tea dir", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// import { readDir, BaseDirectory } from '@tauri-apps/api/fs';
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
|
@ -8,12 +7,8 @@ import { mkdirp } from "mkdirp";
|
||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
import { SemVer, isValidSemVer } from "@tea/libtea";
|
import { SemVer, isValidSemVer } from "@tea/libtea";
|
||||||
import { execSync } from "child_process";
|
import { execSync } from "child_process";
|
||||||
|
import chokidar from "chokidar";
|
||||||
type Dir = {
|
import { MainWindowNotifier } from "./types";
|
||||||
name: string;
|
|
||||||
path: string;
|
|
||||||
children?: Dir[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type ParsedVersion = { full_name: string; semVer: SemVer };
|
type ParsedVersion = { full_name: string; semVer: SemVer };
|
||||||
|
|
||||||
|
@ -38,9 +33,18 @@ export const getGuiPath = () => {
|
||||||
return path.join(getTeaPath(), "tea.xyz/gui");
|
return path.join(getTeaPath(), "tea.xyz/gui");
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getInstalledPackages(): Promise<InstalledPackage[]> {
|
export async function getInstalledVersionsForPackage(fullName: string): Promise<InstalledPackage> {
|
||||||
const pkgsPath = getTeaPath();
|
const pkgsPath = path.join(getTeaPath(), fullName);
|
||||||
|
const result = await findInstalledVersions(pkgsPath);
|
||||||
|
const pkg = result.find((v) => v.full_name === fullName);
|
||||||
|
return pkg ?? { full_name: fullName, installed_versions: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getInstalledPackages(): Promise<InstalledPackage[]> {
|
||||||
|
return findInstalledVersions(getTeaPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findInstalledVersions(pkgsPath: string): Promise<InstalledPackage[]> {
|
||||||
if (!fs.existsSync(pkgsPath)) {
|
if (!fs.existsSync(pkgsPath)) {
|
||||||
log.info(`packages path ${pkgsPath} does not exist, no installed packages`);
|
log.info(`packages path ${pkgsPath} does not exist, no installed packages`);
|
||||||
return [];
|
return [];
|
||||||
|
@ -89,33 +93,6 @@ const parseVersionFromPath = (versionPath: string): ParsedVersion | null => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const semverTest =
|
|
||||||
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/g;
|
|
||||||
|
|
||||||
export const getPkgBottles = (packageDir: Dir): string[] => {
|
|
||||||
log.info("getting installed bottle for ", packageDir);
|
|
||||||
const bottles: string[] = [];
|
|
||||||
|
|
||||||
const pkg = packageDir.path.split(".tea/")[1];
|
|
||||||
const version = pkg.split("/v")[1];
|
|
||||||
|
|
||||||
const isVersion = semverTest.test(version) || !isNaN(+version) || version === "*";
|
|
||||||
|
|
||||||
if (version && isVersion) {
|
|
||||||
bottles.push(pkg);
|
|
||||||
} else if (packageDir?.children?.length) {
|
|
||||||
const childBottles = packageDir.children
|
|
||||||
.map(getPkgBottles)
|
|
||||||
.reduce((arr, bottles) => [...arr, ...bottles], []);
|
|
||||||
bottles.push(...childBottles);
|
|
||||||
}
|
|
||||||
|
|
||||||
const foundBottles = bottles.filter((b) => b !== undefined).sort(); // ie: ["gohugo.io/v*", "gohugo.io/v0", "gohugo.io/v0.108", "gohugo.io/v0.108.0"]
|
|
||||||
|
|
||||||
log.info(`Found ${foundBottles.length} bottles from `, packageDir);
|
|
||||||
return foundBottles;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const deepReadDir = async ({
|
export const deepReadDir = async ({
|
||||||
dir,
|
dir,
|
||||||
continueDeeper,
|
continueDeeper,
|
||||||
|
@ -181,7 +158,7 @@ export async function deletePackageFolder(fullName, version) {
|
||||||
try {
|
try {
|
||||||
const foldPath = path.join(getTeaPath(), fullName, `v${version}`);
|
const foldPath = path.join(getTeaPath(), fullName, `v${version}`);
|
||||||
log.info("rm:", foldPath);
|
log.info("rm:", foldPath);
|
||||||
await fs.rmdirSync(foldPath, { recursive: true });
|
await fs.rmSync(foldPath, { recursive: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
}
|
}
|
||||||
|
@ -217,3 +194,51 @@ export async function cacheImage(url: string): Promise<string> {
|
||||||
|
|
||||||
return `file://${imagePath}`;
|
return `file://${imagePath}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let watcher: chokidar.FSWatcher | null = null;
|
||||||
|
|
||||||
|
export async function startMonitoringTeaDir(mainWindowNotifier: MainWindowNotifier) {
|
||||||
|
if (watcher) {
|
||||||
|
log.info("Watcher already started");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dir = path.join(getTeaPath(), "**/v*");
|
||||||
|
log.info(`Start monitoring tea dir: ${dir}}`);
|
||||||
|
|
||||||
|
watcher = chokidar.watch(dir, {
|
||||||
|
ignoreInitial: true,
|
||||||
|
persistent: true,
|
||||||
|
followSymlinks: false,
|
||||||
|
depth: 5,
|
||||||
|
ignored: ["**/var/pantry/projects/**", "**/local/tmp/**", "**/share/**"]
|
||||||
|
});
|
||||||
|
|
||||||
|
watcher
|
||||||
|
.on("addDir", (pth) => {
|
||||||
|
const dir = path.dirname(pth);
|
||||||
|
const version = path.basename(pth);
|
||||||
|
if (isValidSemVer(version) && !fs.lstatSync(pth).isSymbolicLink()) {
|
||||||
|
const full_name = dir.split(".tea/")[1];
|
||||||
|
log.info(`Monitor - Added Package: ${full_name} v${version}`);
|
||||||
|
mainWindowNotifier("pkg-modified", { full_name, version, type: "add" });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("unlinkDir", (pth) => {
|
||||||
|
// FIXME: unlinkDir does not always fire, this is a bug in chokidar
|
||||||
|
const dir = path.dirname(pth);
|
||||||
|
const version = path.basename(pth);
|
||||||
|
if (isValidSemVer(version)) {
|
||||||
|
const full_name = dir.split(".tea/")[1];
|
||||||
|
log.info(`Monitor - Removed Package: ${full_name} v${version}`);
|
||||||
|
mainWindowNotifier("pkg-modified", { full_name, version, type: "remove" });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("error", (error) => log.error(`Watcher error: ${error}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function stopMonitoringTeaDir() {
|
||||||
|
log.info("Stop monitoring tea dir");
|
||||||
|
await watcher?.close();
|
||||||
|
watcher = null;
|
||||||
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
"axios": "^1.3.2",
|
"axios": "^1.3.2",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
|
"chokidar": "^3.5.3",
|
||||||
"custom-electron-titlebar": "4.2.0-beta.0",
|
"custom-electron-titlebar": "4.2.0-beta.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"electron-context-menu": "^3.6.1",
|
"electron-context-menu": "^3.6.1",
|
||||||
|
|
|
@ -48,6 +48,15 @@ export async function getInstalledPackages(): Promise<InstalledPackage[]> {
|
||||||
return pkgs;
|
return pkgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getInstalledVersionsForPackage(fullName: string): Promise<InstalledPackage> {
|
||||||
|
log.info("getting installed versions for package: ", fullName);
|
||||||
|
const result = await ipcRenderer.invoke("get-installed-package-versions", fullName);
|
||||||
|
if (result instanceof Error) {
|
||||||
|
throw result;
|
||||||
|
}
|
||||||
|
return result as InstalledPackage;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getPackages(): Promise<GUIPackage[]> {
|
export async function getPackages(): Promise<GUIPackage[]> {
|
||||||
const [packages, installedPackages] = await Promise.all([
|
const [packages, installedPackages] = await Promise.all([
|
||||||
getDistPackages(),
|
getDistPackages(),
|
||||||
|
@ -278,3 +287,17 @@ export const isDev = async () => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const monitorTeaDir = async () => {
|
||||||
|
const result = await ipcRenderer.invoke("monitor-tea-dir");
|
||||||
|
if (result instanceof Error) {
|
||||||
|
throw result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stopMonitoringTeaDir = async () => {
|
||||||
|
const result = await ipcRenderer.invoke("stop-monitor-tea-dir");
|
||||||
|
if (result instanceof Error) {
|
||||||
|
throw result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -202,6 +202,13 @@ export async function getDistPackages(): Promise<Package[]> {
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getInstalledVersionsForPackage(full_name: string): Promise<Package> {
|
||||||
|
return (packages.find((pkg) => pkg.full_name === full_name) ?? {
|
||||||
|
full_name,
|
||||||
|
installed_versions: []
|
||||||
|
}) as Package;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getPackages(): Promise<GUIPackage[]> {
|
export async function getPackages(): Promise<GUIPackage[]> {
|
||||||
return packages.map((pkg) => {
|
return packages.map((pkg) => {
|
||||||
return {
|
return {
|
||||||
|
@ -399,3 +406,11 @@ export async function openPackageEntrypointInTerminal(pkg: string) {
|
||||||
export const pollDeviceSession = async () => {
|
export const pollDeviceSession = async () => {
|
||||||
console.log("do nothing");
|
console.log("do nothing");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const monitorTeaDir = async () => {
|
||||||
|
console.log("do nothing");
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stopMonitoringTeaDir = async () => {
|
||||||
|
console.log("do nothing");
|
||||||
|
};
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
import { getPkgBottles } from "../tea-dir";
|
|
||||||
|
|
||||||
describe("tea-dir module", () => {
|
|
||||||
it("should getPkgBottles from nested Dir object/s", () => {
|
|
||||||
const results = getPkgBottles({
|
|
||||||
name: "kkos",
|
|
||||||
path: "/Users/x/.tea/github.com/kkos",
|
|
||||||
children: [
|
|
||||||
{ name: ".DS_Store", path: "/Users/x/.tea/github.com/kkos/.DS_Store" },
|
|
||||||
{
|
|
||||||
name: "oniguruma",
|
|
||||||
path: "/Users/x/.tea/github.com/kkos/oniguruma",
|
|
||||||
children: [
|
|
||||||
{ name: ".DS_Store", path: "/Users/x/.tea/github.com/kkos/oniguruma/.DS_Store" },
|
|
||||||
{
|
|
||||||
path: "/Users/x/.tea/github.com/kkos/oniguruma/v6",
|
|
||||||
name: "v6",
|
|
||||||
children: [
|
|
||||||
{ name: ".DS_Store", path: "/Users/x/.tea/github.com/kkos/oniguruma/v6/.DS_Store" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "v*",
|
|
||||||
path: "/Users/x/.tea/github.com/kkos/oniguruma/v*",
|
|
||||||
children: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "v6.9.8",
|
|
||||||
path: "/Users/x/.tea/github.com/kkos/oniguruma/v6.9.8",
|
|
||||||
children: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "v6.9",
|
|
||||||
path: "/Users/x/.tea/github.com/kkos/oniguruma/v6.9",
|
|
||||||
children: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(results).toEqual([
|
|
||||||
"github.com/kkos/oniguruma/v*",
|
|
||||||
"github.com/kkos/oniguruma/v6",
|
|
||||||
"github.com/kkos/oniguruma/v6.9",
|
|
||||||
"github.com/kkos/oniguruma/v6.9.8"
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,32 +0,0 @@
|
||||||
// import { app } from 'electron';
|
|
||||||
// import fs from 'fs';
|
|
||||||
// import { join } from 'upath';
|
|
||||||
|
|
||||||
type Dir = {
|
|
||||||
name: string;
|
|
||||||
path: string;
|
|
||||||
children?: Dir[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const semverTest =
|
|
||||||
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/g;
|
|
||||||
|
|
||||||
export const getPkgBottles = (packageDir: Dir): string[] => {
|
|
||||||
const bottles: string[] = [];
|
|
||||||
|
|
||||||
const pkg = packageDir.path.split(".tea/")[1];
|
|
||||||
const version = pkg.split("/v")[1];
|
|
||||||
|
|
||||||
const isVersion = semverTest.test(version) || !isNaN(+version) || version === "*";
|
|
||||||
|
|
||||||
if (version && isVersion) {
|
|
||||||
bottles.push(pkg);
|
|
||||||
} else if (packageDir?.children?.length) {
|
|
||||||
const childBottles = packageDir.children
|
|
||||||
.map(getPkgBottles)
|
|
||||||
.reduce((arr, bottles) => [...arr, ...bottles], []);
|
|
||||||
bottles.push(...childBottles);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bottles.filter((b) => b !== undefined).sort(); // ie: ["gohugo.io/v*", "gohugo.io/v0", "gohugo.io/v0.108", "gohugo.io/v0.108.0"]
|
|
||||||
};
|
|
|
@ -12,7 +12,10 @@ import {
|
||||||
writePackageCache,
|
writePackageCache,
|
||||||
syncPantry,
|
syncPantry,
|
||||||
cacheImageURL,
|
cacheImageURL,
|
||||||
listenToChannel
|
listenToChannel,
|
||||||
|
getInstalledVersionsForPackage,
|
||||||
|
monitorTeaDir,
|
||||||
|
stopMonitoringTeaDir
|
||||||
} from "@native";
|
} from "@native";
|
||||||
|
|
||||||
import { getReadme, getContributors, getRepoAsPackage } from "$libs/github";
|
import { getReadme, getContributors, getRepoAsPackage } from "$libs/github";
|
||||||
|
@ -26,7 +29,6 @@ import withRetry from "$libs/utils/retry";
|
||||||
|
|
||||||
import log from "$libs/logger";
|
import log from "$libs/logger";
|
||||||
import { isPackageUpToDate } from "../packages/pkg-utils";
|
import { isPackageUpToDate } from "../packages/pkg-utils";
|
||||||
import withDelay from "$libs/utils/delay";
|
|
||||||
|
|
||||||
import { indexPackages, searchPackages } from "$libs/search-index";
|
import { indexPackages, searchPackages } from "$libs/search-index";
|
||||||
|
|
||||||
|
@ -150,6 +152,7 @@ const init = async function () {
|
||||||
packageMap.set(cachedPkgs);
|
packageMap.set(cachedPkgs);
|
||||||
|
|
||||||
await refreshPackages();
|
await refreshPackages();
|
||||||
|
await monitorTeaDir();
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
log.info("packages store: initialized!");
|
log.info("packages store: initialized!");
|
||||||
|
@ -201,12 +204,20 @@ const refreshPackages = async () => {
|
||||||
refreshTimeoutId = setTimeout(() => refreshPackages(), packageRefreshInterval); // refresh every hour
|
refreshTimeoutId = setTimeout(() => refreshPackages(), packageRefreshInterval); // refresh every hour
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const refreshSinglePackage = async (fullName: string) => {
|
||||||
|
log.info(`refreshing single package: ${fullName}`);
|
||||||
|
const result = await getInstalledVersionsForPackage(fullName);
|
||||||
|
log.info(`package: ${fullName} has installed versions:`, result.installed_versions);
|
||||||
|
updatePackage(fullName, { installed_versions: result.installed_versions });
|
||||||
|
};
|
||||||
|
|
||||||
// Destructor for the package store
|
// Destructor for the package store
|
||||||
const destroy = () => {
|
const destroy = async () => {
|
||||||
isDestroyed = true;
|
isDestroyed = true;
|
||||||
if (refreshTimeoutId) {
|
if (refreshTimeoutId) {
|
||||||
clearTimeout(refreshTimeoutId);
|
clearTimeout(refreshTimeoutId);
|
||||||
}
|
}
|
||||||
|
await stopMonitoringTeaDir();
|
||||||
log.info("packages store: destroyed");
|
log.info("packages store: destroyed");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -218,7 +229,7 @@ const installPkg = async (pkg: GUIPackage, version?: string) => {
|
||||||
await installPackage(pkg, versionToInstall);
|
await installPackage(pkg, versionToInstall);
|
||||||
trackInstall(pkg.full_name);
|
trackInstall(pkg.full_name);
|
||||||
|
|
||||||
await refreshPackages(); // helps e2e tests might not be the most efficient but helps
|
await refreshSinglePackage(pkg.full_name);
|
||||||
|
|
||||||
notificationStore.add({
|
notificationStore.add({
|
||||||
message: `Package ${pkg.full_name} v${versionToInstall} has been installed.`
|
message: `Package ${pkg.full_name} v${versionToInstall} has been installed.`
|
||||||
|
@ -252,9 +263,7 @@ const uninstallPkg = async (pkg: GUIPackage) => {
|
||||||
await deletePkg(pkg, v);
|
await deletePkg(pkg, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePackage(pkg.full_name, {
|
await refreshSinglePackage(pkg.full_name);
|
||||||
installed_versions: []
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
notificationStore.add({
|
notificationStore.add({
|
||||||
|
@ -300,6 +309,7 @@ listenToChannel("install-progress", ({ full_name, progress }: any) => {
|
||||||
updatePackage(full_name, { install_progress_percentage: progress });
|
updatePackage(full_name, { install_progress_percentage: progress });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: perhaps this can be combined with pkg-modified?
|
||||||
listenToChannel("pkg-installed", ({ full_name, version }: any) => {
|
listenToChannel("pkg-installed", ({ full_name, version }: any) => {
|
||||||
if (!full_name) {
|
if (!full_name) {
|
||||||
return;
|
return;
|
||||||
|
@ -307,6 +317,13 @@ listenToChannel("pkg-installed", ({ full_name, version }: any) => {
|
||||||
updatePackage(full_name, {}, version);
|
updatePackage(full_name, {}, version);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
listenToChannel("pkg-modified", ({ full_name }: any) => {
|
||||||
|
if (!full_name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refreshSinglePackage(full_name);
|
||||||
|
});
|
||||||
|
|
||||||
// This is only used for uninstall now
|
// This is only used for uninstall now
|
||||||
export const withFakeLoader = (
|
export const withFakeLoader = (
|
||||||
pkg: GUIPackage,
|
pkg: GUIPackage,
|
||||||
|
|
|
@ -52,6 +52,7 @@ importers:
|
||||||
axios: ^1.3.2
|
axios: ^1.3.2
|
||||||
bcryptjs: ^2.4.3
|
bcryptjs: ^2.4.3
|
||||||
buffer: ^6.0.3
|
buffer: ^6.0.3
|
||||||
|
chokidar: ^3.5.3
|
||||||
concurrently: ^7.6.0
|
concurrently: ^7.6.0
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
custom-electron-titlebar: 4.2.0-beta.0
|
custom-electron-titlebar: 4.2.0-beta.0
|
||||||
|
@ -115,6 +116,7 @@ importers:
|
||||||
axios: 1.4.0
|
axios: 1.4.0
|
||||||
bcryptjs: 2.4.3
|
bcryptjs: 2.4.3
|
||||||
buffer: 6.0.3
|
buffer: 6.0.3
|
||||||
|
chokidar: 3.5.3
|
||||||
custom-electron-titlebar: 4.2.0-beta.0_electron@22.1.0
|
custom-electron-titlebar: 4.2.0-beta.0_electron@22.1.0
|
||||||
dayjs: 1.11.7
|
dayjs: 1.11.7
|
||||||
electron-context-menu: 3.6.1
|
electron-context-menu: 3.6.1
|
||||||
|
|
Loading…
Reference in a new issue