Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Convert sendMessage and onMessage to asynchronous get and call style

License

Notifications You must be signed in to change notification settings

lyswhut/message2call

Repository files navigation

Message to call

Convert Send Message and on Message to asynchronous get and call style.

+--------------------------+           +--------------------------+
|        Main Thread       |           |       Worker Thread      |
+--------------------------+           +--------------------------+
|                          |           |      Expose Object {     |
|   await remote.hello()  ---------------->     hello() {}        |
|                          |           |      }                   |
+--------------------------+           +--------------------------+  

It supports message sending and receiving scenarios in workers, websockets, and more.

Installation

  • Use npm install
# install
npm install message2call
// import
import * as message2call from 'message2call'
  • Use script link
<script src="./message2call.min.js"></script>

How to use

see demo

index.html File:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../dist/message2call.min.js"></script>
  <script>
    const worker = new Worker('./worker.js')
    const exposeObj = {
      getName(fromName) {
        return 'hello ' + fromName + ', I am index.html'
      },
    }
    const message2call = Message2call.createMessage2Call({
      /**
       * required expose object
       */
      exposeObj: exposeObj,
      /**
       * send message function
       */
      sendMessage: function(data) {
        worker.message(data)
      }
    })
    worker.onmessage = (event) => {
      message2call.message(event.data)
    }

    (async() => {
      const remote = message2call.remote
      const remoteName = await remote.name
      console.log('[index]', 'remote name is ' + remoteName)

      const result = await remote.count(6)
      console.log('[index]', result)
    })()
  </script>
</body>
</html>

worker.js File:

importScripts('../dist/message2call.min.js')

const exposeObj = {
  name: 'worker.js',
  async count(num) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(num + 2)
      }, 2000);
    })
  },
}
const message2call = Message2call.createMessage2Call({
  /**
   * required expose object
   */
  exposeObj: exposeObj,
  /**
   * send message function
   */
  sendMessage: function(data) {
    postMessage(data)
  },
})
onmessage = (event) => {
  message2call.message(event.data)
}

(async() => {
  const name = await message2call.remote.getName('worker.js')
  console.log('[worker]', name)
})()

Options

interface Options {
  /**
   * required expose object
   */
  exposeObj: Readonly<Record<string, ((...args: any[]) => any) | string | number | object>>
  /**
   * send message function
   */
  sendMessage: (data: Record<string, unknown>) => void
  /**
   * on call error hook
   */
  onError?: (err: Error, path: string[], groupName: string | null) => viod
  /**
   * call timeout, 0 will be no timeout
   */
  timeout?: number
  /**
   * whether the call fails to send the call stack
   */
  isSendErrorStack?: boolean
  /**
   * convert call params
   */
  onCallBeforeParams?: (rawArgs: any[]) => any[]
}
type createMessage2Call = <T>(options: Options) => {
  /**
   * remote expose object
   */
  remote: T;
  /**
   * create remote expose object of group calls
   */
  createRemoteGroup<T_1>(groupName: string, options?: {
    /**
     * call timeout, 0 will be no timeout, default use global timeout
     */
    timeout?: number;
    /**
     * whether to use queue calls
     */
    queue?: boolean;
  }): T_1;
  /**
   * on message function
   */
  message: ({ name, path, error, data }: any) => void;
  /**
   * destroy
   */
  destroy: () => void;
}
/**
 * create a expose callback
 */
type createProxyCallback = <T extends Function>(callback: T) => T & { releaseProxy: () => void };
/**
 * release all created expose callback
 */
type releaseAllProxyCallback = () => void;

CHANGELOG

See CHANGELOG.md

Thanks

Inspired by comlink: https://github.com/GoogleChromeLabs/comlink

LICENSE

MIT

About

Convert sendMessage and onMessage to asynchronous get and call style

Resources

License

Stars

Watchers

Forks