From dae5d019996af590ede3f72b81fbac8fa583f05f Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 16 Jul 2024 11:28:20 +0200 Subject: [PATCH] API: async signal integration migration --- pkgs/clan-app/clan_app/api/__init__.py | 5 ++--- pkgs/clan-app/clan_app/views/webview.py | 1 - pkgs/clan-cli/clan_cli/api/__init__.py | 5 +---- pkgs/webview-ui/app/src/api.ts | 16 ++++++++++++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/pkgs/clan-app/clan_app/api/__init__.py b/pkgs/clan-app/clan_app/api/__init__.py index 3c22182ad..797e63cbb 100644 --- a/pkgs/clan-app/clan_app/api/__init__.py +++ b/pkgs/clan-app/clan_app/api/__init__.py @@ -29,8 +29,7 @@ class ImplFunc(GObject.Object, Generic[P, B]): "returns": (GObject.SignalFlags.RUN_FIRST, None, [GResult]), } - def returns(self, result: B) -> None: - method_name = self.__class__.__name__ + def returns(self, method_name: str, result: B) -> None: if self.op_key is None: raise ValueError(f"op_key is not set for the function {method_name}") self.emit("returns", GResult(result, method_name, self.op_key)) @@ -109,7 +108,7 @@ class GObjApi: def async_run(self, *args: Any, **kwargs: dict[str, Any]) -> bool: assert plain_method is not None result = plain_method(*args, **kwargs) - self.returns(result) + self.returns(method_name=name, result=result) return GLib.SOURCE_REMOVE return cast(type[ImplFunc], GenericFnRuntime) diff --git a/pkgs/clan-app/clan_app/views/webview.py b/pkgs/clan-app/clan_app/views/webview.py index 9ce50f465..bca421107 100644 --- a/pkgs/clan-app/clan_app/views/webview.py +++ b/pkgs/clan-app/clan_app/views/webview.py @@ -116,7 +116,6 @@ class WebExecutor(GObject.Object): result = dict() result["result"] = dataclass_to_dict(data.result) result["op_key"] = data.op_key - serialized = json.dumps(result, indent=4) log.debug(f"Result: {serialized}") # Use idle_add to queue the response call to js on the main GTK thread diff --git a/pkgs/clan-cli/clan_cli/api/__init__.py b/pkgs/clan-cli/clan_cli/api/__init__.py index 555d6c006..e93269107 100644 --- a/pkgs/clan-cli/clan_cli/api/__init__.py +++ b/pkgs/clan-cli/clan_cli/api/__init__.py @@ -22,14 +22,12 @@ class ApiError: class SuccessDataClass(Generic[ResponseDataType]): status: Annotated[Literal["success"], "The status of the response."] data: ResponseDataType - op_key: str | None @dataclass class ErrorDataClass: status: Literal["error"] errors: list[ApiError] - op_key: str | None ApiResponse = SuccessDataClass[ResponseDataType] | ErrorDataClass @@ -109,11 +107,10 @@ API.register(open_file) ) -> ApiResponse[T]: try: data: T = fn(*args, **kwargs) - return SuccessDataClass(status="success", data=data, op_key=op_key) + return SuccessDataClass(status="success", data=data) except ClanError as e: return ErrorDataClass( status="error", - op_key=op_key, errors=[ ApiError( message=e.msg, diff --git a/pkgs/webview-ui/app/src/api.ts b/pkgs/webview-ui/app/src/api.ts index ac919b440..1c74e4fa9 100644 --- a/pkgs/webview-ui/app/src/api.ts +++ b/pkgs/webview-ui/app/src/api.ts @@ -20,6 +20,12 @@ export type ErrorData = Extract< export type ClanOperations = { [K in OperationNames]: (str: string) => void; }; + +export interface GtkResponse { + result: T; + op_key: string; +} + declare global { interface Window { clan: ClanOperations; @@ -74,9 +80,9 @@ function createFunctions( registry[operationName][id] = fn; window.clan[operationName] = (s: string) => { - const f = (response: OperationResponse) => { + const f = (response: GtkResponse>) => { if (response.op_key === id) { - registry[operationName][id](response); + registry[operationName][id](response.result); } }; deserialize(f)(s); @@ -126,10 +132,12 @@ export const callApi = ( }; const deserialize = - (fn: (response: T) => void) => + (fn: (response: GtkResponse) => void) => (str: string) => { try { - fn(JSON.parse(str) as T); + const r = JSON.parse(str) as GtkResponse; + console.log("Received: ", r); + fn(r); } catch (e) { console.log("Error parsing JSON: ", e); console.log({ download: () => download("error.json", str) });