6.1.2 • Published 1 year ago

delight-rpc v6.1.2

Weekly downloads
361
License
MIT
Repository
github
Last release
1 year ago

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
6.1.0

1 year ago

6.1.2

1 year ago

6.1.1

1 year ago

6.0.1

1 year ago

6.0.0

1 year ago

5.1.0

1 year ago

5.0.4

1 year ago

5.0.3

1 year ago

5.0.2

1 year ago

5.0.1

1 year ago

5.0.0

1 year ago

4.3.2

1 year ago

4.3.0

2 years ago

4.2.4

2 years ago

4.2.3

2 years ago

4.2.2

2 years ago

4.2.1

2 years ago

4.2.0

2 years ago

3.1.1

2 years ago

3.1.0

2 years ago

3.0.0

2 years ago

4.1.0

2 years ago

4.0.0

2 years ago

2.1.2

2 years ago

2.1.1

2 years ago

2.1.0

2 years ago

1.2.0

2 years ago

1.3.1

2 years ago

1.2.2

2 years ago

1.3.0

2 years ago

1.2.1

2 years ago

1.1.2

2 years ago

2.0.0

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago

0.1.22

2 years ago

0.2.0

2 years ago

0.1.20

3 years ago

0.1.21

3 years ago

0.1.19

3 years ago

0.1.18

3 years ago

0.1.16

3 years ago

0.1.17

3 years ago

0.1.15

3 years ago

0.1.14

3 years ago

0.1.13

3 years ago

0.1.10

3 years ago

0.1.11

3 years ago

0.1.12

3 years ago

0.1.9

3 years ago

0.1.8

3 years ago

0.1.7

3 years ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.4

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago