fix: plugin & model catalog import cache are not cleared properly (#437)

* fix: plugin catalog cache is not wiped properly

* fix: import cache issue
This commit is contained in:
Louis 2023-10-25 01:06:37 +07:00 committed by GitHub
parent 914b4082a9
commit df5d75d1f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 97 additions and 40 deletions

View File

@ -1,2 +1,3 @@
declare const PLUGIN_NAME: string;
declare const MODULE_PATH: string;
declare const PLUGIN_CATALOG: string;

View File

@ -216,6 +216,9 @@ export function init({ register }: { register: RegisterExtensionPoint }) {
register(DataService.GetBotById, getBotById.name, getBotById);
register(DataService.DeleteBot, deleteBot.name, deleteBot);
register(DataService.UpdateBot, updateBot.name, updateBot);
// for plugin manifest
register(DataService.GetPluginManifest, getPluginManifest.name, getPluginManifest)
}
function getConversations(): Promise<any> {
@ -323,3 +326,20 @@ function getBotById(botId: string): Promise<any> {
return Promise.reject(err);
});
}
/**
* Retrieves the plugin manifest by importing the remote model catalog and clearing the cache to get the latest version.
* A timestamp is added to the URL to prevent caching.
* @returns A Promise that resolves with the plugin manifest.
*/
function getPluginManifest(): Promise<any> {
// Clear cache to get the latest model catalog
delete require.cache[
require.resolve(/* webpackIgnore: true */ PLUGIN_CATALOG)
];
// Import the remote model catalog
// Add a timestamp to the URL to prevent caching
return import(
/* webpackIgnore: true */ PLUGIN_CATALOG + `?t=${Date.now()}`
).then((module) => module.default);
}

View File

@ -40,8 +40,12 @@
"node_modules"
],
"dependencies": {
"@janhq/core": "^0.1.6",
"@janhq/core": "^0.1.7",
"pouchdb-find": "^8.0.1",
"pouchdb-node": "^8.0.1"
}
},
"bundleDependencies": [
"pouchdb-node",
"pouchdb-find"
]
}

View File

@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "es2016",
"module": "ES6",
"module": "esnext",
"moduleResolution": "node",
"outDir": "./dist",
"esModuleInterop": true,

View File

@ -19,6 +19,9 @@ module.exports = {
new webpack.DefinePlugin({
PLUGIN_NAME: JSON.stringify(packageJson.name),
MODULE_PATH: JSON.stringify(`${packageJson.name}/${packageJson.module}`),
PLUGIN_CATALOG: JSON.stringify(
"https://cdn.jsdelivr.net/npm/@janhq/plugin-catalog@latest/dist/index.js"
),
}),
],
output: {

View File

@ -8,19 +8,24 @@ import {
} from "@janhq/core";
import { parseToModel } from "./helper";
const downloadModel = (product) => downloadFile(product.downloadUrl, product.fileName);
const downloadModel = (product) =>
downloadFile(product.downloadUrl, product.fileName);
const deleteModel = (path) => deleteFile(path);
async function getConfiguredModels() {
// Clear cache to get the latest model catalog
delete require.cache[MODEL_CATALOG_URL];
// Import the remote model catalog
const module = require(MODEL_CATALOG_URL);
return module.default.map((e) => {
return parseToModel(e);
});
/**
* Retrieves a list of configured models from the model catalog URL.
* @returns A Promise that resolves to an array of configured models.
*/
async function getConfiguredModels(): Promise<any> {
// Add a timestamp to the URL to prevent caching
return import(
/* webpackIgnore: true */ MODEL_CATALOG_URL + `?t=${Date.now()}`
).then((module) =>
module.default.map((e) => {
return parseToModel(e);
})
);
}
/**
@ -44,7 +49,11 @@ function storeModel(model: any) {
* @param model Product
*/
function updateFinishedDownloadAt(_id: string): Promise<any> {
return store.updateMany("models", { _id }, { time: Date.now(), finishDownloadAt: 1 });
return store.updateMany(
"models",
{ _id },
{ time: Date.now(), finishDownloadAt: 1 }
);
}
/**
@ -84,14 +93,38 @@ function onStart() {
export function init({ register }: { register: RegisterExtensionPoint }) {
register(PluginService.OnStart, PLUGIN_NAME, onStart);
register(ModelManagementService.DownloadModel, downloadModel.name, downloadModel);
register(
ModelManagementService.DownloadModel,
downloadModel.name,
downloadModel
);
register(ModelManagementService.DeleteModel, deleteModel.name, deleteModel);
register(ModelManagementService.GetConfiguredModels, getConfiguredModels.name, getConfiguredModels);
register(
ModelManagementService.GetConfiguredModels,
getConfiguredModels.name,
getConfiguredModels
);
register(ModelManagementService.StoreModel, storeModel.name, storeModel);
register(ModelManagementService.UpdateFinishedDownloadAt, updateFinishedDownloadAt.name, updateFinishedDownloadAt);
register(
ModelManagementService.UpdateFinishedDownloadAt,
updateFinishedDownloadAt.name,
updateFinishedDownloadAt
);
register(ModelManagementService.DeleteDownloadModel, deleteDownloadModel.name, deleteDownloadModel);
register(ModelManagementService.GetModelById, getModelById.name, getModelById);
register(ModelManagementService.GetFinishedDownloadModels, getFinishedDownloadModels.name, getFinishedDownloadModels);
register(
ModelManagementService.DeleteDownloadModel,
deleteDownloadModel.name,
deleteDownloadModel
);
register(
ModelManagementService.GetModelById,
getModelById.name,
getModelById
);
register(
ModelManagementService.GetFinishedDownloadModels,
getFinishedDownloadModels.name,
getFinishedDownloadModels
);
}

View File

@ -12,9 +12,10 @@ import {
import { MagnifyingGlassIcon } from '@heroicons/react/20/solid'
import classNames from 'classnames'
import { PluginService, preferences } from '@janhq/core'
import { DataService, PluginService, preferences } from '@janhq/core'
import { execute } from '../../../electron/core/plugin-manager/execution/extension-manager'
import LoadingIndicator from './LoadingIndicator'
import { executeSerial } from '@services/pluginService'
export const Preferences = () => {
const [search, setSearch] = useState<string>('')
@ -30,12 +31,10 @@ export const Preferences = () => {
/**
* Loads the plugin catalog module from a CDN and sets it as the plugin catalog state.
* The `webpackIgnore` comment is used to prevent Webpack from bundling the module.
*/
useEffect(() => {
// @ts-ignore
import(/* webpackIgnore: true */ PLUGIN_CATALOGS).then((module) => {
setPluginCatalog(module.default)
executeSerial(DataService.GetPluginManifest).then((data) => {
setPluginCatalog(data)
})
}, [])

View File

@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager'
import { extensionPoints } from '../../electron/core/plugin-manager/execution'
import { SystemMonitoringService } from '@janhq/core'
import { useSetAtom } from 'jotai'
import { totalRamAtom } from '@helpers/atoms/SystemBar.atom'
@ -9,6 +10,9 @@ export default function useGetSystemResources() {
const setTotalRam = useSetAtom(totalRamAtom)
const getSystemResources = async () => {
if (!extensionPoints.get(SystemMonitoringService.GetResourcesInfo)) {
return
}
const resourceInfor = await executeSerial(
SystemMonitoringService.GetResourcesInfo
)

View File

@ -21,14 +21,7 @@ const nextConfig = {
// do some stuff here
config.optimization.minimize = false
config.optimization.minimizer = []
config.plugins = [
...config.plugins,
new webpack.DefinePlugin({
PLUGIN_CATALOGS: JSON.stringify(
'https://cdn.jsdelivr.net/npm/@janhq/plugin-catalog@latest/dist/index.js'
),
}),
]
config.plugins = [...config.plugins, new webpack.DefinePlugin({})]
return config
},
}

View File

@ -14,7 +14,7 @@
"dependencies": {
"@headlessui/react": "^1.7.15",
"@heroicons/react": "^2.0.18",
"@janhq/core": "^0.1.6",
"@janhq/core": "^0.1.7",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-toggle": "^1.0.3",

View File

@ -9,6 +9,8 @@ import {
plugins,
extensionPoints,
} from '@/../../electron/core/plugin-manager/execution/index'
import { executeSerial } from '@services/pluginService'
import { DataService } from '@janhq/core'
const PluginCatalog = () => {
// const [search, setSearch] = useState<string>('')
@ -20,12 +22,10 @@ const PluginCatalog = () => {
/**
* Loads the plugin catalog module from a CDN and sets it as the plugin catalog state.
* The `webpackIgnore` comment is used to prevent Webpack from bundling the module.
*/
useEffect(() => {
// @ts-ignore
import(/* webpackIgnore: true */ PLUGIN_CATALOGS).then((module) => {
setPluginCatalog(module.default)
executeSerial(DataService.GetPluginManifest).then((data) => {
setPluginCatalog(data)
})
}, [])
@ -127,7 +127,7 @@ const PluginCatalog = () => {
return (
<div className="block w-full">
{pluginCatalog.map((item, i) => {
{pluginCatalog?.map((item, i) => {
const isActivePlugin = activePlugins.some((x) => x.name === item.name)
const updateVersionPlugins = Number(
activePlugins
@ -163,7 +163,7 @@ const PluginCatalog = () => {
)}
</div>
<Switch
defaultChecked={isActivePlugin}
checked={isActivePlugin}
onCheckedChange={(e) => {
if (e === true) {
downloadTarball(item.name)