1.0.1 • Published 4 days ago

message-port-rpc v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
4 days ago

message-port-rpc

Turns a MessagePort into an remote procedure call (RPC) stub.

Background

Modern web apps often need to deal with multiple JavaScript workers or VMs. The communication channel is often MessagePort.

By converting a MessagePort into an RPC stub, we can easily offload a Promise function to a different thread.

How to use

On main thread

Creates a new pair of MessagePort, pass one of the port to the worker thread, then create a RPC stub on another port.

import { messagePortRPC } from 'message-port-rpc';

// TypeScript: define the function type.
type Fn = (x: number, y: number) => Promise<number>;

// Loads a Web Worker.
const worker = new Worker('./static/worker/js/main.js');

// Creates a new pair of `MessagePort` dedicated for RPC.
const { port1, port2 } = new MessageChannel();

// Sends the dedicated port to the worker.
worker.postMessage(undefined, [port2]);

// Creates a function stub.
const callFunction = messagePortRPC<Fn>(port1);

// Calls the function stub.
const result: number = await callFunction(1, 2);

On worker thread

Receives the MessagePort and registers an RPC function on the port.

import { messagePortRPC } from 'message-port-rpc';

// TypeScript: define the function type.
type Fn = (x: number, y: number) => Promise<number>;

// Receives the port dedicated for RPC.
addEventListener('message', ({ ports }) => {
  // Registers an RPC function on the received `MessagePort`.
  messagePortRPC<Fn>(ports[0], (x, y) => Promise.resolve(x + y));
});

API

function messagePortRPC<T extends (...args: any[]) => Promise<unknown>>(
  port: MessagePort,
  fn?: T
): {
  (...args: Parameters<T>): ReturnType<T>;

  withOptions: (
    args: Parameters<T>,
    init: {
      signal?: AbortSignal;
      tranfer?: Transferable[];
    }
  ) => ReturnType<T>;
};

Behaviors

Why use a dedicated MessagePort?

Instead of multiplexing multiple messages into a single MessagePort, a dedicated MessagePort simplifies the code, and easier to secure the channel.

Internally, for every call, we create a new pair of MessagePort. The result of the call is passed through the MessagePort. When the call is resolved/rejected/aborted, the MessagePort will be shutdown.

Contributions

Like us? Star us.

Want to make it better? File us an issue.

Don't like something you see? Submit a pull request.

1.0.2-main.702443b

2 months ago

1.0.2-main.da38399

5 months ago

1.0.1

8 months ago

1.0.1-main.e99cfe8

8 months ago

1.0.1-main.3023174

8 months ago

1.0.2-main.e994a23

8 months ago

1.0.1-main.1a66599

8 months ago

1.0.1-main.43112ea

8 months ago

1.0.1-main.035b23c

9 months ago

1.0.1-main.c41dd57

9 months ago

1.0.1-main.3dce907

9 months ago

1.0.1-main.3d2f274

8 months ago

1.0.1-main.0f65c6d

9 months ago

1.0.1-main.b188066

8 months ago

1.0.1-main.adf2e33

9 months ago

1.0.1-main.55dbe15

8 months ago

1.0.1-main.04201c1

8 months ago

1.0.1-main.687566

8 months ago

1.0.1-main.0f38eb4

8 months ago

1.0.1-main.3531c68

8 months ago

1.0.1-main.bda13c5

8 months ago

1.0.0

1 year ago

1.0.1-main.4b5eddf

11 months ago

1.0.1-main.6539423

10 months ago

1.0.1-main.acca1b1

10 months ago

1.0.0-main.92dff70

11 months ago