82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
@use itertools::Itertools;
|
|
@use crate::data::RPC;
|
|
@use crate::generators::ts_c::*;
|
|
|
|
@(rpc: &RPC)
|
|
@for e in &rpc.enums {
|
|
export enum @e.name @{
|
|
@for (k,v) in &e.values { @k = @v,
|
|
}
|
|
@}
|
|
}
|
|
@for s in &rpc.structs {
|
|
export interface @s.name @{
|
|
@for f in &s.fields { @f.name: @ty_to_str(&f.ty);
|
|
}
|
|
@}
|
|
}
|
|
|
|
interface _WSResponse @{
|
|
id: number;
|
|
data: any;
|
|
@}
|
|
|
|
interface _WSWaitingEntry @{
|
|
ok: (v: any) => void;
|
|
err: (reason?: any) => void;
|
|
@}
|
|
|
|
export class MRPCConnector @{
|
|
url: string;
|
|
socket: WebSocket;
|
|
nmi: number;
|
|
waiting: @{ [id: number]: _WSWaitingEntry @};
|
|
streams: @{ [id: number]: (v: any) => void @};
|
|
|
|
private open() @{
|
|
this.socket = new WebSocket(this.url);
|
|
this.socket.onmessage = ev => @{
|
|
const data = JSON.parse(ev.data) as _WSResponse;
|
|
if (data.id in this.streams) @{
|
|
this.streams[data.id](data.data);
|
|
if (data.data == null)
|
|
delete this.streams[data.id];
|
|
@} else if (data.id in this.waiting) @{
|
|
this.waiting[data.id].ok(data.data);
|
|
delete this.waiting[data.id];
|
|
@} else @{
|
|
console.log(`Got unexpected message: $@{data@}`);
|
|
@}
|
|
@}
|
|
this.socket.onerror = () => setTimeout(() => @{this.open();@}, 2500);
|
|
this.socket.onclose = () => setTimeout(() => @{this.open();@}, 2500);
|
|
@}
|
|
|
|
private get_prom<T>(id: number): Promise<T> @{
|
|
return new Promise<T>((ok, err) => @{ this.waiting[id] = @{ok, err@}; @});
|
|
@}
|
|
|
|
public constructor(url: string) @{
|
|
this.url = url;
|
|
this.nmi = 0;
|
|
this.waiting = @{@};
|
|
this.streams = @{@};
|
|
this.open();
|
|
@}
|
|
|
|
@for s in &rpc.services { @for m in &s.methods {
|
|
public @(s.name)_@(m.name)(@method_args(m))@method_ret(m) @{
|
|
const __msg = @{
|
|
id: this.nmi++,
|
|
service: '@s.name',
|
|
method: '@m.name',
|
|
data: @{@m.args.iter().map(|a| &a.name).join(",")@}
|
|
@};
|
|
@if m.ret.is_some() && !m.ret_stream {const __p = this.get_prom<@ty_to_str(m.ret.as_ref().unwrap())>(__msg.id);}
|
|
else if m.ret_stream {this.streams[__msg.id] = __cbk;}
|
|
this.socket.send(JSON.stringify(__msg));
|
|
@if m.ret.is_some() && !m.ret_stream {return __p;}
|
|
@}
|
|
}}
|
|
@}
|