You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
LAPTOP-S9HJSOEB\昊天 8001cd7178 第一次上传 11 months ago
..
dist 第一次上传 11 months ago
LICENSE 第一次上传 11 months ago
README.md 第一次上传 11 months ago
package.json 第一次上传 11 months ago

README.md

birpc

NPM version

Message-based two-way remote procedure call. Useful for WebSockets and Workers communication.

Features

  • Intuitive - call remote functions just like locals, with Promise to get the response
  • TypeScript - safe function calls for arguments and returns
  • Protocol agonostic - WebSocket, MessageChannel, any protocols with messages communication would work!
  • Zero deps, ~0.5KB

Examples

Using WebSocket

When using WebSocket, you need to pass your custom serializer and deserializer.

Client

import type { ServerFunctions } from './types'

const ws = new WebSocket('ws://url')

const clientFunctions: ClientFunctions = {
  hey(name: string) {
    return `Hey ${name} from client`
  }
}

const rpc = createBirpc<ServerFunctions>(
  clientFunctions,
  {
    post: data => ws.send(data),
    on: fn => ws.on('message', fn),
    // these are required when using WebSocket
    serialize: v => JSON.stringify(v),
    deserialize: v => JSON.parse(v),
  },
)

await rpc.hi('Client') // Hi Client from server

Server

import type { ClientFunctions } from './types'
import { WebSocketServer } from 'ws'

const serverFunctions: ServerFunctions = {
  hi(name: string) {
    return `Hi ${name} from server`
  }
}

const wss = new WebSocketServer()

wss.on('connection', (ws) => {
  const rpc = createBirpc<ClientFunctions>(
    serverFunctions,
    {
      post: data => ws.send(data),
      on: fn => ws.on('message', fn),
      serialize: v => JSON.stringify(v),
      deserialize: v => JSON.parse(v),
    },
  )

  await rpc.hey('Server') // Hey Server from client
})

Circular References

As JSON.stringify does not supporting circular references, we recommend using structured-clone-es as the serializer when you expect to have circular references.

import { parse, stringify } from 'structured-clone-es'

const rpc = createBirpc<ServerFunctions>(
  functions,
  {
    post: data => ws.send(data),
    on: fn => ws.on('message', fn),
    // use structured-clone-es as serializer
    serialize: v => stringify(v),
    deserialize: v => parse(v),
  },
)

Using MessageChannel

MessageChannel will automatically serialize the message and support circular references out-of-box.

export const channel = new MessageChannel()

Bob

import type { AliceFunctions } from './types'
import { channel } from './channel'

const Bob: BobFunctions = {
  hey(name: string) {
    return `Hey ${name}, I am Bob`
  }
}

const rpc = createBirpc<AliceFunctions>(
  Bob,
  {
    post: data => channel.port1.postMessage(data),
    on: fn => channel.port1.on('message', fn),
  },
)

await rpc.hi('Bob') // Hi Bob, I am Alice

Alice

import type { BobFunctions } from './types'
import { channel } from './channel'

const Alice: AliceFunctions = {
  hi(name: string) {
    return `Hi ${name}, I am Alice`
  }
}

const rpc = createBirpc<BobFunctions>(
  Alice,
  {
    post: data => channel.port2.postMessage(data),
    on: fn => channel.port2.on('message', fn),
  },
)

await rpc.hey('Alice') // Hey Alice, I am Bob

One-to-multiple Communication

Refer to ./test/group.test.ts as an example.

Sponsors

License

MIT License © 2021 Anthony Fu