diff --git a/package.json b/package.json index b309d17..b45d439 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "joplin-plugin-note-categorization", - "version": "0.1.11", + "version": "0.1.12", "scripts": { "dist": "webpack --env joplin-plugin-config=buildMain && webpack --env joplin-plugin-config=buildExtraScripts && npm run copyAssets && webpack --env joplin-plugin-config=createArchive", "prepare": "npm run dist", diff --git a/src/manifest.json b/src/manifest.json index d2dbd20..708b497 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 1, "id": "com.harsh16gupta.notecategorization", "app_min_version": "3.5", - "version": "0.1.11", + "version": "0.1.12", "name": "Note Categorization Plugin", "description": "AI-based note categorisation: clusters notes semantically, suggests tags and notebook structures, and detects stale notes.", "author": "Harsh Gupta", diff --git a/src/panel/setupPanel.ts b/src/panel/setupPanel.ts index 8bec5e7..3396f70 100644 --- a/src/panel/setupPanel.ts +++ b/src/panel/setupPanel.ts @@ -33,6 +33,10 @@ export async function setupPanel(operationState: OperationState): Promise { switch (msg.type) { case 'run': { + if (operationState.inProgress) { + return panelState; + } + operationState.inProgress = true; panelState = { type: 'status', text: 'Starting pipeline...' }; log('Panel: starting pipeline'); @@ -59,6 +63,7 @@ export async function setupPanel(operationState: OperationState): Promise { + operationState.inProgress = false; lastResultsState = { strategies, notes, @@ -69,6 +74,7 @@ export async function setupPanel(operationState: OperationState): Promise { + operationState.inProgress = false; panelState = { type: 'error', message }; }, }, @@ -106,6 +112,11 @@ export async function setupPanel(operationState: OperationState): Promise = ({ chil ) { startPolling(); } + } else { + // IPC may have failed under heavy load (e.g., during model loading + // or embedding). Start a brief recovery poll to check if a pipeline + // is actually running in the background. + let recoveryAttempts = 0; + const MAX_RECOVERY_ATTEMPTS = 5; + const recoveryInterval = setInterval(async () => { + recoveryAttempts++; + try { + const state = await webviewApi.postMessage({ + type: 'poll', + }); + if (state && state.type !== 'idle') { + clearInterval(recoveryInterval); + handlePollResponseRef.current(state); + if ( + state.type === 'status' || + state.type === 'progress' || + state.type === 'apply_status' || + state.type === 'apply_progress' || + state.type === 'undo_status' || + state.type === 'undo_progress' + ) { + startPolling(); + } + } else if (recoveryAttempts >= MAX_RECOVERY_ATTEMPTS) { + clearInterval(recoveryInterval); + } + } catch { + if (recoveryAttempts >= MAX_RECOVERY_ATTEMPTS) { + clearInterval(recoveryInterval); + } + } + }, 1000); } }) .catch((err) => {