Merge pull request 'API: async signal integration migration' (#1762) from hsjobeki/clan-core:hsjobeki-main into main

This commit is contained in:
clan-bot
2024-07-16 09:37:25 +00:00
4 changed files with 15 additions and 12 deletions

View File

@@ -29,8 +29,7 @@ class ImplFunc(GObject.Object, Generic[P, B]):
"returns": (GObject.SignalFlags.RUN_FIRST, None, [GResult]), "returns": (GObject.SignalFlags.RUN_FIRST, None, [GResult]),
} }
def returns(self, result: B) -> None: def returns(self, method_name: str, result: B) -> None:
method_name = self.__class__.__name__
if self.op_key is None: if self.op_key is None:
raise ValueError(f"op_key is not set for the function {method_name}") raise ValueError(f"op_key is not set for the function {method_name}")
self.emit("returns", GResult(result, method_name, self.op_key)) 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: def async_run(self, *args: Any, **kwargs: dict[str, Any]) -> bool:
assert plain_method is not None assert plain_method is not None
result = plain_method(*args, **kwargs) result = plain_method(*args, **kwargs)
self.returns(result) self.returns(method_name=name, result=result)
return GLib.SOURCE_REMOVE return GLib.SOURCE_REMOVE
return cast(type[ImplFunc], GenericFnRuntime) return cast(type[ImplFunc], GenericFnRuntime)

View File

@@ -116,7 +116,6 @@ class WebExecutor(GObject.Object):
result = dict() result = dict()
result["result"] = dataclass_to_dict(data.result) result["result"] = dataclass_to_dict(data.result)
result["op_key"] = data.op_key result["op_key"] = data.op_key
serialized = json.dumps(result, indent=4) serialized = json.dumps(result, indent=4)
log.debug(f"Result: {serialized}") log.debug(f"Result: {serialized}")
# Use idle_add to queue the response call to js on the main GTK thread # Use idle_add to queue the response call to js on the main GTK thread

View File

@@ -22,14 +22,12 @@ class ApiError:
class SuccessDataClass(Generic[ResponseDataType]): class SuccessDataClass(Generic[ResponseDataType]):
status: Annotated[Literal["success"], "The status of the response."] status: Annotated[Literal["success"], "The status of the response."]
data: ResponseDataType data: ResponseDataType
op_key: str | None
@dataclass @dataclass
class ErrorDataClass: class ErrorDataClass:
status: Literal["error"] status: Literal["error"]
errors: list[ApiError] errors: list[ApiError]
op_key: str | None
ApiResponse = SuccessDataClass[ResponseDataType] | ErrorDataClass ApiResponse = SuccessDataClass[ResponseDataType] | ErrorDataClass
@@ -109,11 +107,10 @@ API.register(open_file)
) -> ApiResponse[T]: ) -> ApiResponse[T]:
try: try:
data: T = fn(*args, **kwargs) 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: except ClanError as e:
return ErrorDataClass( return ErrorDataClass(
status="error", status="error",
op_key=op_key,
errors=[ errors=[
ApiError( ApiError(
message=e.msg, message=e.msg,

View File

@@ -20,6 +20,12 @@ export type ErrorData<T extends OperationNames> = Extract<
export type ClanOperations = { export type ClanOperations = {
[K in OperationNames]: (str: string) => void; [K in OperationNames]: (str: string) => void;
}; };
export interface GtkResponse<T> {
result: T;
op_key: string;
}
declare global { declare global {
interface Window { interface Window {
clan: ClanOperations; clan: ClanOperations;
@@ -74,9 +80,9 @@ function createFunctions<K extends OperationNames>(
registry[operationName][id] = fn; registry[operationName][id] = fn;
window.clan[operationName] = (s: string) => { window.clan[operationName] = (s: string) => {
const f = (response: OperationResponse<K>) => { const f = (response: GtkResponse<OperationResponse<K>>) => {
if (response.op_key === id) { if (response.op_key === id) {
registry[operationName][id](response); registry[operationName][id](response.result);
} }
}; };
deserialize(f)(s); deserialize(f)(s);
@@ -126,10 +132,12 @@ export const callApi = <K extends OperationNames>(
}; };
const deserialize = const deserialize =
<T>(fn: (response: T) => void) => <T>(fn: (response: GtkResponse<T>) => void) =>
(str: string) => { (str: string) => {
try { try {
fn(JSON.parse(str) as T); const r = JSON.parse(str) as GtkResponse<T>;
console.log("Received: ", r);
fn(r);
} catch (e) { } catch (e) {
console.log("Error parsing JSON: ", e); console.log("Error parsing JSON: ", e);
console.log({ download: () => download("error.json", str) }); console.log({ download: () => download("error.json", str) });