You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
5.4 KiB
155 lines
5.4 KiB
// tslint:disable:interface-over-type-literal |
|
export type DefaultRequestTypes = {}; |
|
export type DefaultResponseTypes = {}; |
|
export type DefaultErrorType = { |
|
code: number; |
|
message: string; |
|
data?: any; |
|
}; |
|
export type DefaultNotificationTypes = {}; |
|
// tslint:enable:interface-over-type-literal |
|
|
|
// export interface RpcTypes { |
|
// RequestTypes: DefaultRequestTypes; |
|
// ResponseTypes: DefaultResponseTypes; |
|
// NotificationTypes: DefaultNotificationTypes; |
|
// ErrorType: DefaultErrorType; |
|
// } |
|
|
|
export interface Request<RequestTypes = DefaultRequestTypes, |
|
Method extends keyof RequestTypes = keyof RequestTypes> { |
|
type: "request"; |
|
id: number; |
|
method: Method; |
|
params: RequestTypes[Method]; |
|
} |
|
|
|
export interface ResponseBase<Method> { |
|
type: "response"; |
|
id: number; |
|
method: Method; |
|
} |
|
|
|
export interface SuccessData<ResponseType> { |
|
result: "success"; |
|
data: ResponseType; |
|
} |
|
|
|
export interface ErrorData<ErrorType> { |
|
result: "error"; |
|
error: ErrorType; |
|
} |
|
|
|
export type ResponseData<ResponseTypes, ErrorType, |
|
Method extends keyof ResponseTypes = keyof ResponseTypes> = |
|
SuccessData<ResponseTypes[Method]> | ErrorData<ErrorType>; |
|
|
|
export type Response<ResponseTypes, |
|
ErrorType = DefaultErrorType, |
|
Method extends keyof ResponseTypes = keyof ResponseTypes> = |
|
ResponseBase<Method> & ResponseData<ResponseTypes, ErrorType, Method>; |
|
|
|
export interface Notification<NotificationTypes = DefaultNotificationTypes, |
|
Method extends keyof NotificationTypes = keyof NotificationTypes> { |
|
type: "notification"; |
|
method: Method; |
|
data: NotificationTypes[Method]; |
|
} |
|
|
|
export type Message<RequestTypes = DefaultRequestTypes, |
|
ResponseTypes = DefaultResponseTypes, |
|
ErrorType = DefaultErrorType, |
|
NotificationTypes = DefaultNotificationTypes> = |
|
Request<RequestTypes> | |
|
Response<ResponseTypes, ErrorType> | |
|
Notification<NotificationTypes>; |
|
|
|
// export type TypesMessage<Types extends RpcTypes = RpcTypes> = |
|
// Message<Types["RequestTypes"], Types["ResponseTypes"], Types["ErrorType"], Types["NotificationTypes"]>; |
|
|
|
export function isRequestMethod<Method extends keyof RequestTypes, RequestTypes>( |
|
message: Request<RequestTypes>, method: Method, |
|
): message is Request<RequestTypes, Method> { |
|
return message.method === method; |
|
} |
|
|
|
export function isResponseMethod<Method extends keyof ResponseTypes, ErrorType, ResponseTypes>( |
|
message: Response<ResponseTypes, ErrorType>, method: Method, |
|
): message is Response<ResponseTypes, ErrorType, Method> { |
|
return message.method === method; |
|
} |
|
|
|
export function isNotificationMethod<Method extends keyof NotificationTypes, NotificationTypes = any>( |
|
message: Notification<NotificationTypes>, method: Method, |
|
): message is Notification<NotificationTypes, Method> { |
|
return message.method === method; |
|
} |
|
|
|
export type IRequestHandler<RequestTypes, ResponseTypes extends { [M in Method]: any }, ErrorType, |
|
Method extends keyof RequestTypes> = |
|
(request: RequestTypes[Method]) => Promise<ResponseData<ResponseTypes, ErrorType, Method>>; |
|
|
|
export type RequestHandlers<RequestTypes, ResponseTypes extends { [M in keyof RequestTypes]: any }, ErrorType> = { |
|
[Method in keyof RequestTypes]: |
|
IRequestHandler<RequestTypes, ResponseTypes, ErrorType, Method>; |
|
}; |
|
|
|
export type IResponseHandler<ResponseTypes, ErrorType, |
|
Method extends keyof ResponseTypes = keyof ResponseTypes> = |
|
(response: ResponseData<ResponseTypes, ErrorType, Method>) => void; |
|
|
|
export interface ResponseHandlers<ResponseTypes = DefaultResponseTypes, ErrorType = DefaultErrorType> { |
|
[id: number]: IResponseHandler<ResponseTypes, ErrorType>; |
|
} |
|
|
|
export type NotificationHandler<NotificationTypes, Method extends keyof NotificationTypes> = |
|
(notification: NotificationTypes[Method]) => void; |
|
|
|
export type NotificationHandlers<NotificationTypes> = { |
|
[Method in keyof NotificationTypes]: NotificationHandler<NotificationTypes, Method>; |
|
}; |
|
|
|
export function listRequestHandlerMethods<RequestTypes, |
|
ResponseTypes extends { [Method in keyof RequestTypes]: any }, ErrorType>( |
|
handlers: RequestHandlers<RequestTypes, ResponseTypes, ErrorType>, |
|
): Array<keyof RequestTypes> { |
|
return Object.keys(handlers) as any; |
|
} |
|
|
|
export function listNotificationHandlerMethods<NotificationTypes>( |
|
handlers: NotificationHandlers<NotificationTypes>, |
|
): Array<keyof NotificationTypes> { |
|
return Object.keys(handlers) as any; |
|
} |
|
|
|
export async function handleRequest<RequestTypes, |
|
ResponseTypes extends { [Method in keyof RequestTypes]: any }, ErrorType>( |
|
handlers: RequestHandlers<RequestTypes, ResponseTypes, ErrorType>, |
|
message: Request<RequestTypes>, |
|
): Promise<ResponseData<ResponseTypes, ErrorType>> { |
|
const handler = handlers[message.method]; |
|
if (!handler) { |
|
throw new Error("No handler for request method " + message.method); |
|
} |
|
return handler(message.params); |
|
} |
|
|
|
export function handleResponse<ResponseTypes, ErrorType>( |
|
handlers: ResponseHandlers<ResponseTypes, ErrorType>, |
|
message: Response<ResponseTypes, ErrorType>) { |
|
const handler = handlers[message.id]; |
|
if (!handler) { |
|
return; |
|
} |
|
return handler(message); |
|
} |
|
|
|
export function handleNotification<NotificationTypes>( |
|
handlers: NotificationHandlers<NotificationTypes>, |
|
message: Notification<NotificationTypes>) { |
|
const handler = handlers[message.method]; |
|
if (!handler) { |
|
throw new Error("No handler for notification method " + message.method); |
|
} |
|
return handler(message.data); |
|
}
|
|
|