Add native self-hosted instance connection to fluxer_desktop
Trimmed monorepo checkout (fluxer_desktop + packages/voice_engine_v2 + tools/ci) with a "Connect to a Different Server" menu item and popout that lets the desktop app switch to any self-hosted Fluxer instance, plus fixes for well-known discovery on single-domain self-hosted deployments and a false-positive ERR_ABORTED on same-origin client redirects during the switch. Defaults to chat.fluxr.chat and uses an isolated userData directory from the official build.
This commit is contained in:
+169
@@ -0,0 +1,169 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {EventEmitter} from 'node:events';
|
||||
|
||||
export type GameCaptureInjectionMethod = 'auto' | 'remote-thread' | 'set-windows-hook';
|
||||
|
||||
export type CaptureStrategyName = 'game-hook' | 'wgc' | 'dxgi-duplication' | 'window-gdi';
|
||||
|
||||
export interface ScreenCaptureRect {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface ScreenCaptureOptions {
|
||||
sourceId: string;
|
||||
sourceKind: 'screen' | 'window' | 'game';
|
||||
width?: number;
|
||||
height?: number;
|
||||
frameRate?: number;
|
||||
hookDllPath?: string;
|
||||
hookDllPathX86?: string;
|
||||
injectionMethod?: GameCaptureInjectionMethod;
|
||||
captureId?: string;
|
||||
colorRange?: 'full' | 'limited';
|
||||
colorSpace?: 'rec709' | 'srgb';
|
||||
showCursorClicks?: boolean;
|
||||
captureRect?: ScreenCaptureRect;
|
||||
frameSinkHandle?: unknown;
|
||||
nativeFrameSinkRequired?: boolean;
|
||||
}
|
||||
|
||||
export interface ScreenCaptureStartResult {
|
||||
width: number;
|
||||
height: number;
|
||||
frameRate: number;
|
||||
pixelFormat: 'nv12' | 'bgra';
|
||||
}
|
||||
|
||||
export interface ScreenCaptureSourceDescriptor {
|
||||
kind: 'screen' | 'window' | 'game';
|
||||
id: string;
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
targetPid?: number;
|
||||
}
|
||||
|
||||
export interface AvailabilityInfo {
|
||||
available: boolean;
|
||||
backend: string;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface CaptureDiagnostics {
|
||||
state: number;
|
||||
apiType: number;
|
||||
transport: number;
|
||||
fallbackReason: number;
|
||||
captureFlags: number;
|
||||
width: number;
|
||||
height: number;
|
||||
dxgiFormat: number;
|
||||
frameCounter: number;
|
||||
droppedFrameCounter: number;
|
||||
lastPresentTimestampUs: number;
|
||||
lastError: number;
|
||||
requestedInjectionMethod: GameCaptureInjectionMethod;
|
||||
injectionMethod: 'remote-thread' | 'set-windows-hook';
|
||||
activeStrategy: CaptureStrategyName;
|
||||
lastFallbackReason: string;
|
||||
startOptions: ScreenCaptureStartOptionsDiagnostics;
|
||||
frameSinkAccepted: number;
|
||||
frameSinkCoalesced: number;
|
||||
frameSinkRejected: number;
|
||||
mediaFramesDroppedWithoutSink: number;
|
||||
cpuFallbackFramesDropped: number;
|
||||
}
|
||||
|
||||
export interface ScreenCaptureStartOptionsDiagnostics {
|
||||
colorRange?: 'full' | 'limited';
|
||||
colorSpace?: 'rec709' | 'srgb';
|
||||
showCursorClicks?: boolean;
|
||||
captureRect?: ScreenCaptureRect;
|
||||
unsupportedOptions: Array<'showCursorClicks' | 'captureRect' | 'colorRange' | 'colorSpace'>;
|
||||
}
|
||||
|
||||
export interface SharedTextureHandleInfo {
|
||||
handle: bigint;
|
||||
width: number;
|
||||
height: number;
|
||||
dxgiFormat: number;
|
||||
timestampUs: number;
|
||||
}
|
||||
|
||||
export interface EncoderAttachDiagnostics {
|
||||
attached: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
capacity: number;
|
||||
framesSubmitted: number;
|
||||
framesDropped: number;
|
||||
ringFullEvents: number;
|
||||
failedBlits: number;
|
||||
}
|
||||
|
||||
export interface FrameSinkDiagnostics {
|
||||
accepted: number;
|
||||
coalesced: number;
|
||||
rejected: number;
|
||||
mediaFramesDroppedWithoutSink: number;
|
||||
cpuFallbackFramesDropped: number;
|
||||
}
|
||||
|
||||
export interface VulkanLayerRegistrationState {
|
||||
registered: boolean;
|
||||
manifestExists: boolean;
|
||||
dllExists: boolean;
|
||||
manifestPath: string | null;
|
||||
}
|
||||
|
||||
export declare interface ScreenCapture {
|
||||
on(event: 'error', listener: (err: Error) => void): this;
|
||||
on(event: 'closed', listener: () => void): this;
|
||||
on(event: 'stalled', listener: (message?: string) => void): this;
|
||||
on(event: 'diagnostic', listener: (message?: string) => void): this;
|
||||
on(event: string | symbol, listener: (...args: Array<unknown>) => void): this;
|
||||
|
||||
off(event: 'error', listener: (err: Error) => void): this;
|
||||
off(event: 'closed', listener: () => void): this;
|
||||
off(event: 'stalled', listener: (message?: string) => void): this;
|
||||
off(event: 'diagnostic', listener: (message?: string) => void): this;
|
||||
off(event: string | symbol, listener: (...args: Array<unknown>) => void): this;
|
||||
|
||||
emit(event: 'error', err: Error): boolean;
|
||||
emit(event: 'closed'): boolean;
|
||||
emit(event: 'stalled', message?: string): boolean;
|
||||
emit(event: 'diagnostic', message?: string): boolean;
|
||||
}
|
||||
|
||||
export declare class ScreenCapture extends EventEmitter {
|
||||
constructor(options?: ScreenCaptureOptions);
|
||||
start(): Promise<ScreenCaptureStartResult | undefined>;
|
||||
stop(): Promise<void>;
|
||||
getDiagnostics(): CaptureDiagnostics | null;
|
||||
getSharedTextureHandle(): SharedTextureHandleInfo | null;
|
||||
attachEncoder(width: number, height: number, frameRate?: number): void;
|
||||
detachEncoder(): void;
|
||||
isEncoderAttached(): boolean;
|
||||
encoderRingFullCount(): number;
|
||||
getEncoderAttachDiagnostics(): EncoderAttachDiagnostics | null;
|
||||
getFrameSinkDiagnostics(): FrameSinkDiagnostics;
|
||||
}
|
||||
|
||||
export declare function isSupported(): boolean;
|
||||
export declare function getAvailability(): AvailabilityInfo;
|
||||
export declare function listSources(): Promise<Array<ScreenCaptureSourceDescriptor>>;
|
||||
export declare function resolveGameHookPath(): string | null;
|
||||
export declare function resolveGameHookPathX86(): string | null;
|
||||
export declare function resolveVulkanLayerManifestPath(): string | null;
|
||||
export declare function registerVulkanLayerManifest(): boolean;
|
||||
export declare function unregisterVulkanLayerManifest(): boolean;
|
||||
export declare function getVulkanLayerRegistrationState(): VulkanLayerRegistrationState;
|
||||
export declare function parseFallbackRecommendation(message: string | undefined): CaptureStrategyName | 'none' | null;
|
||||
export declare function elevateGpuSchedulingPriority(processId?: number, priorityClass?: 'high' | 'realtime'): boolean;
|
||||
export declare function restoreGpuSchedulingPriority(processId?: number): boolean;
|
||||
export declare function __setBindingForTests(binding: unknown): void;
|
||||
export declare const loadError: Error | null;
|
||||
Reference in New Issue
Block a user