mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-17 11:45:05 +02:00
Allow desktop app to connect to selfhosted servers (#4902)
# Description of Changes Changes the desktop app to allow connections to self-hosted servers on first startup. This was quite involved and hit loads of CORS issues all through the stack, but I think it's working now. This also changes the bundled backend to spawn on an OS-decided port rather than always spawning on `8080`, which means that the user can have other things running on port `8080` now and the app will still work fine. There were quite a few places that needed to be updated to decouple the app from explicitly using `8080` and I was originally going to split those changes out into another PR (#4939), but I couldn't get it working independently in the time I had, so the diff here is just going to be complex and contian two distinct changes - sorry 🙁
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { connectionModeService } from '@app/services/connectionModeService';
|
||||
import { tauriBackendService } from '@app/services/tauriBackendService';
|
||||
|
||||
export type ExecutionTarget = 'local' | 'remote';
|
||||
|
||||
export class OperationRouter {
|
||||
private static instance: OperationRouter;
|
||||
|
||||
static getInstance(): OperationRouter {
|
||||
if (!OperationRouter.instance) {
|
||||
OperationRouter.instance = new OperationRouter();
|
||||
}
|
||||
return OperationRouter.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines where an operation should execute
|
||||
* @param _operation - The operation name (for future operation classification)
|
||||
* @returns 'local' or 'remote'
|
||||
*/
|
||||
async getExecutionTarget(_operation?: string): Promise<ExecutionTarget> {
|
||||
const mode = await connectionModeService.getCurrentMode();
|
||||
|
||||
// Current implementation: simple mode-based routing
|
||||
if (mode === 'offline') {
|
||||
return 'local';
|
||||
}
|
||||
|
||||
// In server mode, currently all operations go to remote
|
||||
// Future enhancement: check if operation is "simple" and route to local if so
|
||||
// Example future logic:
|
||||
// if (mode === 'server' && operation && this.isSimpleOperation(operation)) {
|
||||
// return 'local';
|
||||
// }
|
||||
|
||||
return 'remote';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base URL for an operation based on execution target
|
||||
* @param _operation - The operation name (for future operation classification)
|
||||
* @returns Base URL for API calls
|
||||
*/
|
||||
async getBaseUrl(_operation?: string): Promise<string> {
|
||||
const target = await this.getExecutionTarget(_operation);
|
||||
|
||||
if (target === 'local') {
|
||||
// Use dynamically assigned port from backend service
|
||||
const backendUrl = tauriBackendService.getBackendUrl();
|
||||
if (!backendUrl) {
|
||||
throw new Error('Backend URL not available - backend may still be starting');
|
||||
}
|
||||
// Strip trailing slash to avoid double slashes in URLs
|
||||
return backendUrl.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
// Remote: get from server config
|
||||
const serverConfig = await connectionModeService.getServerConfig();
|
||||
if (!serverConfig) {
|
||||
console.warn('No server config found');
|
||||
throw new Error('Server configuration not found');
|
||||
}
|
||||
|
||||
// Strip trailing slash to avoid double slashes in URLs
|
||||
return serverConfig.url.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we're currently in remote mode
|
||||
*/
|
||||
async isRemoteMode(): Promise<boolean> {
|
||||
const mode = await connectionModeService.getCurrentMode();
|
||||
return mode === 'server';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we're currently in offline mode
|
||||
*/
|
||||
async isOfflineMode(): Promise<boolean> {
|
||||
const mode = await connectionModeService.getCurrentMode();
|
||||
return mode === 'offline';
|
||||
}
|
||||
|
||||
// Future enhancement: operation classification
|
||||
// private isSimpleOperation(operation: string): boolean {
|
||||
// const simpleOperations = [
|
||||
// 'rotate',
|
||||
// 'merge',
|
||||
// 'split',
|
||||
// 'extract-pages',
|
||||
// 'remove-pages',
|
||||
// 'reorder-pages',
|
||||
// 'metadata',
|
||||
// ];
|
||||
// return simpleOperations.includes(operation);
|
||||
// }
|
||||
}
|
||||
|
||||
export const operationRouter = OperationRouter.getInstance();
|
||||
Reference in New Issue
Block a user