This is a NAPI
-based NPM package that provides synchronous IPC/RPC using a
simple line protocol. It uses NAPI-RS
under the hood. See
their site for more details as needed.
import { SyncRpcChannel } from "libsyncrpc";
const channel = new SyncRpcChannel("node", "./myscript.js");
const DECODER = new TextDecoder();
channel.registerCallback("callMeMaybe", (method: string, payload: string) => {
console.log(`method '${method}' invoked 'callMeMaybe' callback`);
const parsed = JSON.parse(payload);
parsed.touched = true;
return JSON.stringify(parsed);
});
const result = channel.requestSync("echo", JSON.stringify({hello: "world"}));
console.log(result); // { hello: "world", touched: true }
// Remember to clean up after yourself!
channel.close();
A synchronous RPC channel that allows JavaScript to synchronously call out to a child process and get a response over a line-based protocol, including handling of JavaScript-side callbacks before the call completes.
Requests follow a MessagePack-based "tuple"/array protocol with 3 items:
(<type>, <name>, <payload>)
. All items are binary arrays of 8-bit
integers, including the <type>
and <name>
, to avoid unnecessary
encoding/decoding at the protocol level.
For specific message types and their corresponding protocol behavior, please
see MessageType
below.
declare class SyncRpcChannel {
constructor(exe: string, args: Array<string>);
requestSync(method: string, payload: string): string;
requestBinarySync(method: string, payload: Uint8Array): Uint8Array;
registerCallback(
name: string,
callback: (name: string, payload: string) => string,
): void;
close(): void;
}
Constructs a new SyncRpcChannel
by spawning a child process with the
given exe
executable, and a given set of args
.
constructor(exe: string, args: Array<string>);
Send a request to the child process and wait for a response. The method will not return, synchronously, until a response is received or an error occurs.
This method will take care of encoding and decoding the binary payload to and from a JS string automatically and suitable for smaller payloads.
requestSync(method: string, payload: string): string;
Send a request to the child process and wait for a response. The method will not return, synchronously, until a response is received or an error occurs.
Unlike requestSync
, this method will not do any of its own encoding or
decoding of payload data. Everything will be as sent/received through the
underlying protocol.
requestBinarySync(method: string, payload: Uint8Array): Uint8Array;
Registers a JavaScript callback that the child can invoke before completing a request. The callback will receive a string name and a string payload as its arguments and should return a string as its result.
There is currently no Uint8Array
-only equivalent to this functionality.
If the callback throws, an it will be handled appropriately by
requestSync
and the child will be notified.
registerCallback(name: string, callback: (name: string, payload: string) => string): void;
close(): void;
- Install Rust (note that you may need VS C++ Buil Tools when prompted).
- Install Node.js
- Clone this repository
cd <repo location> && npm i
npm run build
(for production/release build), ornpm run build:debug
(for debug build)
Simply run npm run bench
. It will test against both a Node-based child
process and a Rust-based one, using the same protocol.
rust-analyzer
is the Rust language server you want. It's available pretty
much on everything.
For vscode, you may want to add the following to settings.json
:
{
"rust-analyzer.procMacro.ignored": { "napi-derive": ["napi"] }
}
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit Contributor License Agreements.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.