refactor(web-client): refactor WASM interfaces to remove static consructor functions (#775)

This commit is contained in:
Alex Yusiuk
2025-04-23 09:53:42 -04:00
committed by GitHub
parent d8ab533463
commit aef4b924aa
14 changed files with 63 additions and 108 deletions
+19 -18
View File
@@ -1,30 +1,31 @@
import init, {
import wasm_init, {
setup,
DesktopSize,
DeviceEvent,
InputTransaction,
IronError,
Session,
SessionBuilder,
SessionTerminationInfo,
ClipboardData,
ClipboardItem,
Extension,
} from '../../../crates/ironrdp-web/pkg/ironrdp_web';
export default {
init,
setup,
DesktopSize,
DeviceEvent,
InputTransaction,
IronError,
SessionBuilder,
ClipboardData,
ClipboardItem,
Session,
SessionTerminationInfo,
Extension,
export async function init(log_level: string) {
await wasm_init();
setup(log_level);
}
export const Backend = {
createDesktopSize: DesktopSize.init,
createMouseButtonPressed: DeviceEvent.mouse_button_pressed,
createMouseButtonReleased: DeviceEvent.mouse_button_released,
createMouseMove: DeviceEvent.mouse_move,
createWheelRotations: DeviceEvent.wheel_rotations,
createKeyPressed: DeviceEvent.key_pressed,
createKeyReleased: DeviceEvent.key_released,
createUnicodePressed: DeviceEvent.unicode_pressed,
createUnicodeReleased: DeviceEvent.unicode_released,
createInputTransaction: InputTransaction.init,
createSessionBuilder: SessionBuilder.init,
createClipboardData: ClipboardData.init,
};
export function preConnectionBlob(pcb: string): Extension {
@@ -1,7 +1,6 @@
import type { ClipboardItem } from './ClipboardItem';
export interface ClipboardData {
init(): ClipboardData;
add_text(mime_type: string, text: string): void;
add_binary(mime_type: string, binary: Uint8Array): void;
items(): ClipboardItem[];
@@ -1,6 +1,4 @@
export interface DesktopSize {
width: number;
height: number;
init(width: number, height: number): DesktopSize;
}
@@ -1,10 +1 @@
export interface DeviceEvent {
mouse_button_pressed(button: number): DeviceEvent;
mouse_button_released(button: number): DeviceEvent;
mouse_move(x: number, y: number): DeviceEvent;
wheel_rotations(vertical: boolean, rotation_units: number): DeviceEvent;
key_pressed(scancode: number): DeviceEvent;
key_released(scancode: number): DeviceEvent;
unicode_pressed(unicode: string): DeviceEvent;
unicode_released(unicode: string): DeviceEvent;
}
export type DeviceEvent = unknown;
@@ -1,23 +1,20 @@
import type { DesktopSize } from './DesktopSize';
import type { DeviceEvent } from './DeviceEvent';
import type { InputTransaction } from './InputTransaction';
import type { IronError } from './session-event';
import type { Session } from './Session';
import type { SessionBuilder } from './SessionBuilder';
import type { SessionTerminationInfo } from './SessionTerminationInfo';
import type { ClipboardData } from './ClipboardData';
import type { ClipboardItem } from './ClipboardItem';
export interface RemoteDesktopModule {
init: () => Promise<unknown>;
setup: (logLevel: string) => void;
DesktopSize: DesktopSize;
DeviceEvent: DeviceEvent;
InputTransaction: InputTransaction;
RemoteDesktopError: IronError;
Session: Session;
SessionBuilder: SessionBuilder;
SessionTerminationInfo: SessionTerminationInfo;
ClipboardData: ClipboardData;
ClipboardItem: ClipboardItem;
createDesktopSize(width: number, height: number): DesktopSize;
createMouseButtonPressed(button: number): DeviceEvent;
createMouseButtonReleased(button: number): DeviceEvent;
createMouseMove(x: number, y: number): DeviceEvent;
createWheelRotations(vertical: boolean, rotation_units: number): DeviceEvent;
createKeyPressed(scancode: number): DeviceEvent;
createKeyReleased(scancode: number): DeviceEvent;
createUnicodePressed(unicode: string): DeviceEvent;
createUnicodeReleased(unicode: string): DeviceEvent;
createInputTransaction(): InputTransaction;
createSessionBuilder(): SessionBuilder;
createClipboardData(): ClipboardData;
}
@@ -3,7 +3,6 @@ import type { DesktopSize } from './DesktopSize';
import type { ClipboardData } from './ClipboardData';
export interface SessionBuilder {
init(): SessionBuilder;
/**
* Required
*/
@@ -17,7 +17,6 @@
import { onMount } from 'svelte';
import { loggingService } from './services/logging.service';
import { RemoteDesktopService } from './services/remote-desktop.service';
import { LogType } from './enums/LogType';
import type { ResizeEvent } from './interfaces/ResizeEvent';
import { PublicAPI } from './services/PublicAPI';
import { ScreenScale } from './enums/ScreenScale';
@@ -27,13 +26,11 @@
let {
scale,
verbose,
debugwasm,
flexcenter,
module,
}: {
scale: string;
verbose: 'true' | 'false';
debugwasm: 'OFF' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE';
flexcenter: string;
module: RemoteDesktopModule;
} = $props();
@@ -667,8 +664,6 @@
canvas.width = 800;
canvas.height = 600;
const logLevel = LogType[debugwasm] ?? LogType.INFO;
await remoteDesktopService.init(logLevel);
remoteDesktopService.setCanvas(canvas);
initListeners();
@@ -2,7 +2,6 @@ export * as default from './iron-remote-desktop.svelte';
export type { ResizeEvent } from './interfaces/ResizeEvent';
export type { NewSessionInfo } from './interfaces/NewSessionInfo';
export type { ServerRect } from './interfaces/ServerRect';
export type { DesktopSize } from './interfaces/DesktopSize';
export type { SessionEvent, IronError, IronErrorKind } from './interfaces/session-event';
export type { SessionEventType } from './enums/SessionEventType';
export type { SessionTerminationInfo } from './interfaces/SessionTerminationInfo';
@@ -2,7 +2,6 @@ import { BehaviorSubject, from, Observable, of, Subject } from 'rxjs';
import { loggingService } from './logging.service';
import { catchError, filter, map } from 'rxjs/operators';
import { scanCode } from '../lib/scancodes';
import { LogType } from '../enums/LogType';
import { OS } from '../enums/OS';
import { ModifierKey } from '../enums/ModifierKey';
import { LockKey } from '../enums/LockKey';
@@ -65,14 +64,7 @@ export class RemoteDesktopService {
}
createClipboardData(): ClipboardData {
return this.module.ClipboardData.init();
}
async init(debug: LogType) {
loggingService.info('Load wasm file...');
await this.module.init();
loggingService.info('Initialize the remote desktop module...');
this.module.setup(LogType[debug]);
return this.module.createClipboardData();
}
// If set to false, the clipboard will not be enabled and the callbacks will not be registered to the Rust side
@@ -116,14 +108,12 @@ export class RemoteDesktopService {
if (preventDefault) {
event.preventDefault(); // prevent default behavior (context menu, etc)
}
const mouseFnc = isDown
? this.module.DeviceEvent.mouse_button_pressed
: this.module.DeviceEvent.mouse_button_released;
const mouseFnc = isDown ? this.module.createMouseButtonPressed : this.module.createMouseButtonReleased;
this.doTransactionFromDeviceEvents([mouseFnc(event.button)]);
}
updateMousePosition(position: MousePosition) {
this.doTransactionFromDeviceEvents([this.module.DeviceEvent.mouse_move(position.x, position.y)]);
this.doTransactionFromDeviceEvents([this.module.createMouseMove(position.x, position.y)]);
this.mousePosition.next(position);
}
@@ -132,7 +122,7 @@ export class RemoteDesktopService {
}
connect(config: Config): Observable<NewSessionInfo> {
const sessionBuilder = this.module.SessionBuilder.init();
const sessionBuilder = this.module.createSessionBuilder();
sessionBuilder.proxy_address(config.proxyAddress);
sessionBuilder.destination(config.destination);
@@ -160,7 +150,7 @@ export class RemoteDesktopService {
if (config.desktopSize != null) {
sessionBuilder.desktop_size(
this.module.DesktopSize.init(config.desktopSize.width, config.desktopSize.height),
this.module.createDesktopSize(config.desktopSize.width, config.desktopSize.height),
);
}
@@ -242,7 +232,7 @@ export class RemoteDesktopService {
mouseWheel(event: WheelEvent) {
const vertical = event.deltaY !== 0;
const rotation = vertical ? event.deltaY : event.deltaX;
this.doTransactionFromDeviceEvents([this.module.DeviceEvent.wheel_rotations(vertical, -rotation)]);
this.doTransactionFromDeviceEvents([this.module.createWheelRotations(vertical, -rotation)]);
}
setVisibility(state: boolean) {
@@ -273,7 +263,7 @@ export class RemoteDesktopService {
onClipboardChangedEmpty(): Promise<void> {
const onClipboardChangedPromise = async () => {
await this.session?.on_clipboard_paste(this.module.ClipboardData.init());
await this.session?.on_clipboard_paste(this.module.createClipboardData());
};
return onClipboardChangedPromise();
}
@@ -318,11 +308,11 @@ export class RemoteDesktopService {
let unicodeEvent;
if (evt.type === 'keydown') {
keyEvent = this.module.DeviceEvent.key_pressed;
unicodeEvent = this.module.DeviceEvent.unicode_pressed;
keyEvent = this.module.createKeyPressed;
unicodeEvent = this.module.createUnicodePressed;
} else if (evt.type === 'keyup') {
keyEvent = this.module.DeviceEvent.key_released;
unicodeEvent = this.module.DeviceEvent.unicode_released;
keyEvent = this.module.createKeyReleased;
unicodeEvent = this.module.createUnicodeReleased;
}
let sendAsUnicode = true;
@@ -453,7 +443,7 @@ export class RemoteDesktopService {
}
private doTransactionFromDeviceEvents(deviceEvents: DeviceEvent[]) {
const transaction = this.module.InputTransaction.init();
const transaction = this.module.createInputTransaction();
deviceEvents.forEach((event) => transaction.add_event(event));
this.session?.apply_inputs(transaction);
}
@@ -464,21 +454,18 @@ export class RemoteDesktopService {
const suppr = parseInt('0xE053', 16);
this.doTransactionFromDeviceEvents([
this.module.DeviceEvent.key_pressed(ctrl),
this.module.DeviceEvent.key_pressed(alt),
this.module.DeviceEvent.key_pressed(suppr),
this.module.DeviceEvent.key_released(ctrl),
this.module.DeviceEvent.key_released(alt),
this.module.DeviceEvent.key_released(suppr),
this.module.createKeyPressed(ctrl),
this.module.createKeyPressed(alt),
this.module.createKeyPressed(suppr),
this.module.createKeyReleased(ctrl),
this.module.createKeyReleased(alt),
this.module.createKeyReleased(suppr),
]);
}
private sendMeta() {
const meta = parseInt('0xE05B', 16);
this.doTransactionFromDeviceEvents([
this.module.DeviceEvent.key_pressed(meta),
this.module.DeviceEvent.key_released(meta),
]);
this.doTransactionFromDeviceEvents([this.module.createKeyPressed(meta), this.module.createKeyReleased(meta)]);
}
}
@@ -2,11 +2,11 @@
import { currentSession, userInteractionService } from '../../services/session.service';
import { catchError, filter } from 'rxjs/operators';
import type { UserInteraction, NewSessionInfo } from '../../../static/iron-remote-desktop';
import { preConnectionBlob, displayControl, kdcProxyUrl } from '../../../static/iron-remote-desktop-rdp';
import { preConnectionBlob, displayControl, kdcProxyUrl, init } from '../../../static/iron-remote-desktop-rdp';
import { from, of } from 'rxjs';
import { toast } from '$lib/messages/message-store';
import { showLogin } from '$lib/login/login-store';
import { DesktopSize } from '../../models/desktop-size';
import { onMount } from 'svelte';
let username = 'Administrator';
let password = 'DevoLabs123!';
@@ -15,7 +15,7 @@
let domain = '';
let authtoken = '';
let kdc_proxy_url = '';
let desktopSize = new DesktopSize(1280, 768);
let desktopSize = { width: 1280, height: 720 };
let pcb = '';
let pop_up = false;
let enable_clipboard = true;
@@ -171,6 +171,10 @@
}
});
};
onMount(async () => {
await init('INFO');
});
</script>
<main class="responsive login-container">
@@ -2,7 +2,7 @@
import { onMount } from 'svelte';
import { setCurrentSessionActive, userInteractionService } from '../../services/session.service';
import type { UserInteraction } from '../../../static/iron-remote-desktop';
import IronRdp from '../../../static/iron-remote-desktop-rdp';
import { Backend } from '../../../static/iron-remote-desktop-rdp';
import { preConnectionBlob, displayControl, kdcProxyUrl } from '../../../static/iron-remote-desktop-rdp';
let userInteraction: UserInteraction;
@@ -146,7 +146,7 @@
</label>
</div>
</div>
<iron-remote-desktop debugwasm="INFO" verbose="true" scale="fit" flexcenter="true" module={IronRdp} />
<iron-remote-desktop verbose="true" scale="fit" flexcenter="true" module={Backend} />
</div>
<style>
@@ -3,7 +3,7 @@
import { setCurrentSessionActive, userInteractionService } from '../../services/session.service';
import { showLogin } from '$lib/login/login-store';
import type { UserInteraction } from '../../../static/iron-remote-desktop';
import IronRdp from '../../../static/iron-remote-desktop-rdp';
import { Backend } from '../../../static/iron-remote-desktop-rdp';
let uiService: UserInteraction;
let cursorOverrideActive = false;
@@ -101,7 +101,7 @@
</div>
{/if}
</div>
<iron-remote-desktop debugwasm="INFO" verbose="true" scale="fit" flexcenter="true" module={IronRdp} />
<iron-remote-desktop verbose="true" scale="fit" flexcenter="true" module={Backend} />
</div>
<style>
@@ -1,14 +0,0 @@
import type { DesktopSize as IDesktopSize } from './../../../iron-remote-desktop/src/interfaces/DesktopSize';
export class DesktopSize implements IDesktopSize {
constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
init(width: number, height: number): DesktopSize {
return new DesktopSize(width, height);
}
width: number;
height: number;
}
@@ -1,12 +1,11 @@
import { Guid } from 'guid-typescript';
import type { DesktopSize } from './desktop-size';
export class Session {
id: Guid;
sessionId!: number;
name?: string;
active!: boolean;
desktopSize!: DesktopSize;
desktopSize!: { width: number; height: number };
constructor(name?: string) {
this.id = Guid.create();