Skip to content

Commit

Permalink
Implement Plugin Unload Mechanism
Browse files Browse the repository at this point in the history
Added callbacks for handling plugin unload events. Improved logging consistency and fixed lefthook files to handle multiple node modules paths for various architectures.
  • Loading branch information
qianlifeng committed Jul 30, 2024
1 parent 82efa3b commit 77692ee
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 119 deletions.
105 changes: 56 additions & 49 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -18,58 +18,65 @@ call_lefthook()
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
if test -f "$dir/node_modules/lefthook/bin/index.js"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/Wox.UI.React/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/lefthook/bin/index.js"
then
"$dir/Wox.UI.React/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/Wox/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/lefthook/bin/index.js"
then
"$dir/Wox/node_modules/lefthook/bin/index.js" "$@"

elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/')
if test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/lefthook/bin/index.js"
then
"$dir/Wox.UI.React/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/lefthook/bin/index.js"
then
"$dir/Wox/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"

elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
echo "Can't find lefthook in PATH"
fi
fi
}
Expand Down
105 changes: 56 additions & 49 deletions .husky/prepare-commit-msg
Original file line number Diff line number Diff line change
Expand Up @@ -18,58 +18,65 @@ call_lefthook()
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
if test -f "$dir/node_modules/lefthook/bin/index.js"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/Wox.UI.React/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/lefthook/bin/index.js"
then
"$dir/Wox.UI.React/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/Wox/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/lefthook/bin/index.js"
then
"$dir/Wox/node_modules/lefthook/bin/index.js" "$@"

elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/')
if test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/lefthook/bin/index.js"
then
"$dir/Wox.UI.React/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox.UI.React/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/lefthook/bin/index.js"
then
"$dir/Wox/node_modules/lefthook/bin/index.js" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"
elif test -f "$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
"$dir/Wox/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook" "$@"

elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
echo "Can't find lefthook in PATH"
fi
fi
}
Expand Down
2 changes: 1 addition & 1 deletion Wox.Plugin.Host.Nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"typescript": "^5.2.2"
},
"dependencies": {
"@wox-launcher/wox-plugin": "^0.0.71",
"@wox-launcher/wox-plugin": "^0.0.78",
"dayjs": "^1.11.9",
"promise-deferred": "^2.0.4",
"winston": "^3.10.0",
Expand Down
8 changes: 4 additions & 4 deletions Wox.Plugin.Host.Nodejs/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Wox.Plugin.Host.Nodejs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ wss.on("connection", function connection(ws) {

const ctx = NewContextWithValue(TraceIdKey, jsonRpcRequest.TraceId)

logger.debug(ctx, `receive request from wox: ${JSON.stringify(jsonRpcRequest)}`)
logger.debug(ctx, `receive request from wox, plugin:${jsonRpcRequest.PluginName}, method: ${jsonRpcRequest.Method}`)

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Expand Down
27 changes: 20 additions & 7 deletions Wox.Plugin.Host.Nodejs/src/jsonrpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface PluginJsonRpcResponse {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
export async function handleRequestFromWox(ctx: Context, request: PluginJsonRpcRequest, ws: WebSocket): unknown {
logger.info(ctx, `invoke <${request.PluginName}> method: ${request.Method}, parameters: ${JSON.stringify(request.Params)}`)
logger.info(ctx, `invoke <${request.PluginName}> method: ${request.Method}`)

switch (request.Method) {
case "loadPlugin":
Expand All @@ -63,6 +63,8 @@ export async function handleRequestFromWox(ctx: Context, request: PluginJsonRpcR
return onGetDynamicSetting(ctx, request)
case "onDeepLink":
return onDeepLink(ctx, request)
case "onUnload":
return onUnload(ctx, request)
case "onLLMStream":
return onLLMStream(ctx, request)
default:
Expand All @@ -78,11 +80,11 @@ async function loadPlugin(ctx: Context, request: PluginJsonRpcRequest) {

const module = await import(modulePath)
if (module["plugin"] === undefined || module["plugin"] === null) {
logger.error(ctx, `[${request.PluginName}] plugin doesn't export plugin object`)
logger.error(ctx, `<${request.PluginName}> plugin doesn't export plugin object`)
return
}

logger.info(ctx, `[${request.PluginName}] load plugin successfully`)
logger.info(ctx, `<${request.PluginName}> load plugin successfully`)
pluginInstances.set(request.PluginId, {
Plugin: module["plugin"] as Plugin,
API: {} as PluginAPI,
Expand All @@ -95,14 +97,14 @@ async function loadPlugin(ctx: Context, request: PluginJsonRpcRequest) {
function unloadPlugin(ctx: Context, request: PluginJsonRpcRequest) {
const pluginInstance = pluginInstances.get(request.PluginId)
if (pluginInstance === undefined || pluginInstance === null) {
logger.error(ctx, `[${request.PluginName}] plugin instance not found: ${request.PluginName}`)
logger.error(ctx, `<${request.PluginName}> plugin instance not found: ${request.PluginName}`)
throw new Error(`plugin instance not found: ${request.PluginName}`)
}

delete require.cache[require.resolve(pluginInstance.ModulePath)]
pluginInstances.delete(request.PluginId)

logger.info(ctx, `[${request.PluginName}] unload plugin successfully`)
logger.info(ctx, `<${request.PluginName}> unload plugin successfully`)
}

function getMethod<M extends keyof Plugin>(ctx: Context, request: PluginJsonRpcRequest, methodName: M): Plugin[M] {
Expand Down Expand Up @@ -177,6 +179,17 @@ async function onDeepLink(ctx: Context, request: PluginJsonRpcRequest) {
plugin.API.deepLinkCallbacks.get(callbackId)?.(params)
}

async function onUnload(ctx: Context, request: PluginJsonRpcRequest) {
const plugin = pluginInstances.get(request.PluginId)
if (plugin === undefined || plugin === null) {
logger.error(ctx, `plugin not found: ${request.PluginName}, forget to load plugin?`)
throw new Error(`plugin not found: ${request.PluginName}, forget to load plugin?`)
}

const callbackId = request.Params.CallbackId
await plugin.API.unloadCallbacks.get(callbackId)?.()
}

async function onLLMStream(ctx: Context, request: PluginJsonRpcRequest) {
const plugin = pluginInstances.get(request.PluginId)
if (plugin === undefined || plugin === null) {
Expand Down Expand Up @@ -259,7 +272,7 @@ async function action(ctx: Context, request: PluginJsonRpcRequest) {

const pluginAction = plugin.Actions.get(request.Params.ActionId)
if (pluginAction === undefined || pluginAction === null) {
logger.error(ctx, `[${request.PluginName}] plugin action not found: ${request.PluginName}`)
logger.error(ctx, `<${request.PluginName}> plugin action not found: ${request.PluginName}`)
return
}

Expand All @@ -277,7 +290,7 @@ async function refresh(ctx: Context, request: PluginJsonRpcRequest) {

const pluginRefresh = plugin.Refreshes.get(request.Params.ResultId)
if (pluginRefresh === undefined || pluginRefresh === null) {
logger.error(ctx, `[${request.PluginName}] plugin refresh not found: ${request.PluginName}`)
logger.error(ctx, `<${request.PluginName}> plugin refresh not found: ${request.PluginName}`)
return
}

Expand Down
10 changes: 9 additions & 1 deletion Wox.Plugin.Host.Nodejs/src/pluginAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export class PluginAPI implements PublicAPI {
settingChangeCallbacks: Map<string, (key: string, value: string) => void>
getDynamicSettingCallbacks: Map<string, (key: string) => PluginSettingDefinitionItem>
deepLinkCallbacks: Map<string, (params: MapString) => void>
unloadCallbacks: Map<string, () => Promise<void>>
llmStreamCallbacks: Map<string, AI.ChatStreamFunc>

constructor(ws: WebSocket, pluginId: string, pluginName: string) {
Expand All @@ -24,6 +25,7 @@ export class PluginAPI implements PublicAPI {
this.settingChangeCallbacks = new Map<string, (key: string, value: string) => void>()
this.getDynamicSettingCallbacks = new Map<string, (key: string) => PluginSettingDefinitionItem>()
this.deepLinkCallbacks = new Map<string, (params: MapString) => void>()
this.unloadCallbacks = new Map<string, () => Promise<void>>()
this.llmStreamCallbacks = new Map<string, AI.ChatStreamFunc>()
}

Expand All @@ -32,7 +34,7 @@ export class PluginAPI implements PublicAPI {
const traceId = ctx.Get("traceId") || crypto.randomUUID()

if (method !== "Log") {
logger.info(ctx, `[${this.pluginName}] start invoke method to Wox: ${method}, id: ${requestId} parameters: ${JSON.stringify(params)}`)
logger.info(ctx, `<${this.pluginName}> start invoke method to Wox: ${method}, id: ${requestId}`)
}

this.ws.send(
Expand Down Expand Up @@ -109,6 +111,12 @@ export class PluginAPI implements PublicAPI {
await this.invokeMethod(ctx, "OnDeepLink", { callbackId })
}

async OnUnload(ctx: Context, callback: () => Promise<void>): Promise<void> {
const callbackId = crypto.randomUUID()
this.unloadCallbacks.set(callbackId, callback)
await this.invokeMethod(ctx, "OnUnload", { callbackId })
}

async RegisterQueryCommands(ctx: Context, commands: MetadataCommand[]): Promise<void> {
await this.invokeMethod(ctx, "RegisterQueryCommands", { commands: JSON.stringify(commands) })
}
Expand Down
Loading

0 comments on commit 77692ee

Please sign in to comment.