typescript-webworker-rpc
v0.2.0
Published
Simple promise based RPC between window and worker with TypeScript
Downloads
20
Readme
TypeScript WebWorker RPC
This is a simple RPC utils to build a bridge between window
and worker
as simple way using TypeScript.
Install
yarn add typescript-webworker-rpc
Usage
Quick start
- Define your RPC interface.
interface AccumulatorRPC {
add: (value: number) => void;
get: () => number;
}
- Create an object for server-calling and register handlers.
// Maybe in web-worker context.
let totalValue = 0;
new RPCServer<AccumulatorRPC>(self as any)
.on('add', value => {
totalValue += value;
})
.on('get', () => ({ result: totalValue }));
- Create an object for client-calling.
// Maybe in window context.
const rpc = new RPCClient<AccumulatorRPC>(worker);
await rpc.call('add', 20);
const newValue = await rpc.call('get');
Advanced
Let's write an example that communicates each endpoints with ping and pong messages.
- Write two interfaces for that.
// window -> worker
interface Ping {
ping: () => void;
}
// worker -> window
interface Pong {
pong: () => void;
}
- Write both of client and server using both channels.
// window.ts
const pingRPC = new rpc.RPCClient<Ping>(worker);
new rpc.RPCServer<Pong>(worker).on('pong', async () => {
await pingRPC.call('ping');
});
// worker.ts
const pongRPC = new rpc.RPCClient<Pong>(self as any);
new rpc.RPCServer<Ping>(self as any).on('ping', async () => {
await pongRPC.call('pong');
});
Of course, above example doesn't be terminated because it is the infinity recursive call.
API
RPCClient
A object to call a method to send a request to web-worker side and wait a result using Promise
.
call
await rpc.call(`method-name`, ...parameters);
If you send an ArrayBuffer
to web-worker, you can use like this. If you can transfer the ownership of that object, please use withTransfer
method before calling a call
method.
await rpc.withTransfer([buffer]).call(`addBuffer`, buffer);
Of course, you can use multiple parameters, too.
interface ComplexCall {
awesome: (some: number, thing: string) => void;
}
await rpc.call(`awesome`, 10, 'good');
post
call
method uses a promise
to wait its result from web-worker. But if you want to post a message and don't need to wait for its result, you can use post
method instead. Its return type should be PostReturn
.
interface BufferPost {
addBuffer: (buffer: ArrayBuffer) => PostReturn;
}
rpc.withTransfer([buffer]).post(`addBuffer`, buffer);
It can reduce meaningless waiting costs when you can fire and forget.
onError
If you want to handle an error from worker
, please chain error
handler using onError
method.
rpc.onError(error => console.error);
RPCServer
A object to receive a request from window and response a result.
on
(for call
)
You can write a method call handler like event handler.
rpc.on(`method-name`, `handler => {result, transfer}`, `transfer`);
If your method is a void function, you can write a void handler. But in other cases, a return type should be {result: ReturnType; transfer?: Transferable[] }
because it should support transfer
like postMessage
.
on
(for post
)
If your handler doesn't need to response due to call from post
function, you should use noReturn
option when installing a method handler.
rpc.on(
`addBuffer`,
buffer => {
buffers.push(buffer);
},
{ noReturn: true },
);
Then there is no postMessage
for that.
onError
It is same as RPCClient#onError
.
If you want to handle an error from worker
, please chain error
handler using onError
method.
rpc.onError(error => console.error);
Contributors
Thanks!
License
MIT