A few notes:
1) The context higher-order function will be tedious to define - a lot
more typing than just an extra function argument.
2) As some methods do not require the context function, forgetting to
call it might introduce bugs (await fn will not error out), but
compile checks of the return value type might detect this
Possible solution is to go the GRPC way and allow only a single method
type as a parameter so all server-side method types would look like:
async fn(param: IParam, context: Context) {}
and all client-side method types would look like:
async fn(param: IParam) {}
However, This would deviate from the JSON-RPC standard which allows
multiple arguments to be passed in an array.
Alternatively, context could be passed as a first argument and then
filtered out:
type Arguments<T> = T extends (context: Ctx, ...args: infer A) => infer R
? A
: never
In this case, the type of Ctx would need to be known in advance. Will
have to think about this some more.