delight-rpc
v6.1.2
Published
The easiest-to-use RPC library designed for TypeScript and JavaScript.
Downloads
2,034
Readme
delight-rpc
The easiest-to-use RPC library designed for TypeScript and JavaScript.
Install
npm install --save delight-rpc
# or
yarn add delight-rpc
Usage
Client
import { createClient } from 'delight-rpc'
interface IAPI {
foo(bar: string): string
}
const client = createClient<IAPI>(send)
const result = await client.foo('bar')
BatchClient
import { createBatchProxy, BatchClient } from 'delight-rpc'
interface IAPI {
getNumber(): number
getString(): string
}
const client = new BatchClient(send)
const proxy = createBatchProxy<IAPI>()
const results = await client.parallel(
proxy.getNumber()
, proxy.getString()
)
// `Result` comes from the `return-style` module, it has Rust-like APIs
results[0] // Result<number, Error>
results[1] // Result<string, Error>
Server
import { createResponse, IRequest, IBatchRequest } from 'delight-rpc'
const api: IAPI = {
foo(bar: string) {
return bar
}
}
async function handle(
request: IRequest<unknown> | IBatchRequest<unknown>
): Promise<IResponse<unknown> | IBatchResponse<unknown>> {
return await createResponse(api, request)
}
API
type ImplementationOf<Obj> = {
[Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
Obj[Key] extends (...args: infer Args) => infer Result
? (...args: [...args: Args, signal?: AbortSignal]) => Awaitable<Awaited<Result>>
: ImplementationOf<Obj[Key]>
}
type ParameterValidators<Obj> = Partial<{
[Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
Obj[Key] extends (...args: infer Args) => unknown
? (...args: Args) => void
: ParameterValidators<Obj[Key]>
}>
createClient
type ClientProxy<Obj> = {
[Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
Obj[Key] extends (...args: infer Args) => infer Result
? (...args: [...args: Args, signal?: AbortSignal]) => Promise<Awaited<Result>>
: ClientProxy<Obj[Key]>
}
function createClient<API extends object, DataType = unknown>(
send: (
request: IRequest<DataType>
, signal?: AbortSignal
) => Awaitable<IResponse<DataType>>
, options?: {
parameterValidators?: ParameterValidators<API>
expectedVersion?: string
channel?: string
}
): ClientProxy<API>
For easy distinction, when the method is not available,
MethodNotAvailable
will be thrown instead of the general Error
.
BatchClient
type MapRequestsToResults<RequestTuple extends IRequestForBatchRequest<unknown, unknown>[]> = {
[Index in keyof RequestTuple]:
RequestTuple[Index] extends IRequestForBatchRequest<infer T, unknown>
? Result<T, Error>
: never
}
class BatchClient<DataType = unknown> {
constructor(
send: (batchRequest: IBatchRequest<DataType>) => Awaitable<
| IError
| IBatchResponse<DataType>
>
, options?: {
expectedVersion?: string
channel?: string
}
)
async parallel<T extends IRequestForBatchRequest<unknown, DataType>[]>(
...requests: T
): Promise<MapRequestsToResults<T>>
async series<T extends IRequestForBatchRequest<unknown, DataType>[]>(
...requests: T
): Promise<MapRequestsToResults<T>>
}
createBatchProxy
type BatchClientProxy<Obj, DataType> = {
[Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
Obj[Key] extends (...args: infer Args) => infer Result
? (...args: Args) => IRequestForBatchRequest<Awaited<Result>, DataType>
: BatchClientProxy<Obj[Key], DataType>
}
function createBatchProxy<API extends object, DataType = unknown>(
options?: {
parameterValidators?: ParameterValidators<API>
}
): BatchClientProxy<API, DataType>
createResponse
const AnyChannel
function createResponse<API, DataType>(
api: ImplementationOf<API>
, request: IRequest<DataType> | IBatchRequest<DataType>
, { parameterValidators = {}, version, channel, signal, ownPropsOnly = false }: {
parameterValidators?: ParameterValidators<API>
version?: `${number}.${number}.${number}`
channel?: string | RegExp | typeof AnyChannel
ownPropsOnly?: boolean
signal?: AbortSignal
} = {}
): Promise<null | IResponse<DataType> | IBatchResponse<DataType>>
createResponse
returns null
if the channel does not match.
MethodNotAvailable
class MethodNotAvailable extends CustomError {}
VersionMismatch
class VersionMismatch extends CustomError {}
InternalError
class InternalError extends CustomError {}
isRequst
function isRequest<DataType>(val: unknown): val is IRequest<DataType>
isResult
function isResult<DataType>(val: unknown): val is IResult<DataType>
isError
function isError(val: unknown): val is IError
isBatchRequest
function isBatchRequest<T>(val: unknown): val is IBatchRequest<T>
isBatchResponse
function isBatchResponse<T>(val: unknown): val is IBatchResponse<T>
matchChannel
function matchChannel<DataType>(
message: IDelightRPC
, channel:
| undefined
| string
| RegExp
| typeof AnyChannel
): boolean
createAbort
function createAbort(id: string, channel: string | undefined): IAbort
isAbort
function isAbort(val: unknown): val is IAbort