mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-04-06 03:19:39 +02:00
* Adds a fallback mechanism so the desktop app routes tool operations to the local bundled backend when the user's self-hosted Stirling-PDF server goes offline, and disables tools in the UI that aren't supported locally. * `selfHostedServerMonitor.ts` independently polls the self-hosted server every 15s and exposes which tool endpoints are unavailable when it goes offline * `operationRouter.ts` intercepts operations destined for the self-hosted server and reroutes them to the local bundled backend when the monitor reports it offline * `useSelfHostedToolAvailability.ts` feeds the offline tool set into useToolManagement, disabling affected tools in the UI with a selfHostedOffline reason and banner warning - `SelfHostedOfflineBanner `is a dismissable (session-only) gray bar shown at the top of the UI when in self-hosted mode and the server goes offline. It shows:
64 lines
2.1 KiB
TypeScript
64 lines
2.1 KiB
TypeScript
import { useEffect, useState, useCallback } from 'react';
|
|
import { backendHealthMonitor } from '@app/services/backendHealthMonitor';
|
|
import { selfHostedServerMonitor } from '@app/services/selfHostedServerMonitor';
|
|
import { tauriBackendService } from '@app/services/tauriBackendService';
|
|
import { connectionModeService } from '@app/services/connectionModeService';
|
|
import type { BackendHealthState } from '@app/types/backendHealth';
|
|
|
|
/**
|
|
* Hook to read backend health state for UI (Run button, BackendHealthIndicator).
|
|
*
|
|
* backendHealthMonitor tracks the local bundled backend.
|
|
* selfHostedServerMonitor tracks the remote server in self-hosted mode.
|
|
*
|
|
* isOnline logic:
|
|
* - SaaS mode: true when local backend is healthy
|
|
* - Self-hosted mode (server online): true (remote is up)
|
|
* - Self-hosted mode (server offline, local port known): true so the Run button
|
|
* stays enabled — operationRouter routes supported tools to local
|
|
* - Self-hosted mode (server offline, local port unknown): false
|
|
*/
|
|
export function useBackendHealth() {
|
|
const [health, setHealth] = useState<BackendHealthState>(() => backendHealthMonitor.getSnapshot());
|
|
const [serverStatus, setServerStatus] = useState(
|
|
() => selfHostedServerMonitor.getSnapshot().status
|
|
);
|
|
const [localUrl, setLocalUrl] = useState<string | null>(
|
|
() => tauriBackendService.getBackendUrl()
|
|
);
|
|
const [connectionMode, setConnectionMode] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
void connectionModeService.getCurrentMode().then(setConnectionMode);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
return backendHealthMonitor.subscribe(setHealth);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
return selfHostedServerMonitor.subscribe(state => setServerStatus(state.status));
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
return tauriBackendService.subscribeToStatus(() => {
|
|
setLocalUrl(tauriBackendService.getBackendUrl());
|
|
});
|
|
}, []);
|
|
|
|
const checkHealth = useCallback(async () => {
|
|
return backendHealthMonitor.checkNow();
|
|
}, []);
|
|
|
|
const isOnline =
|
|
connectionMode === 'selfhosted'
|
|
? serverStatus !== 'offline' || !!localUrl
|
|
: health.isOnline;
|
|
|
|
return {
|
|
...health,
|
|
isOnline,
|
|
checkHealth,
|
|
};
|
|
}
|