npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

json-rpc-dual-engine

v0.8.7

Published

JSON-RPC-2.0 client and server protocol-agnostic engine.

Downloads

586

Readme

json-rpc-dual-engine

GitHub Workflow Status (branch) NPM node-current npm GitHub last commit npm

A zero-dependencies protocol agnostic implementation of the JSON-RPC-2.0 spec.

This package includes a client and a server, but you can import either separately without increasing the size of your final build, if you don't need both.

Install

npm install json-rpc-dual-engine

Usage

Server

Create the server with an object that implements the methods to be exposed to the client:

import { JsonRpcServer } from 'json-rpc-dual-engine/server';

const api = {
	multiply(a, b) {
		return a * b;
	},
	ping() {
		return 'pong';
	},
};

const server = new JsonRpcServer({ api });

Register a onresponse callback to receive the json-rpc responses generated by the server:

// `onresponse` will be called whenever the server generates a response.
// It's your job is to send it to the client somehow.
server.onresponse = response => console.log(response);

Then use the accept method to deliver incoming remote method calls to the server. The server validates the json-rpc message call, calls the appropriate registered method, and generate the appropriate json-rpc response based on the return of the registered handler.

// It's your job to receive the request from the client somehow.
const request = '{"jsonrpc":"2.0","method":"multiply","params":[7,11],"id":"1"}';

server.accept(request);
// Output: '{"jsonrpc":"2.0","result":77,"id":"1"}'

Client

Create the client:

import { JsonRpcClient } from 'json-rpc-dual-engine/client';

const client = new JsonRpcClient();

Register a onrequest callack to send requests made by the client to the server.

// It's your job to send the requests to the server somehow.
client.onrequest = request => console.log(request);

client.sendRequest('multiply', [7, 11]);
// Output: '{"jsonrpc":"2.0","method":"multiply","params":[7,11],"id":"1"}'

client.sendNotification('ping'); // no return
// Output: '{"jsonrpc":"2.0","method":"ping"}'

// Or use the proxy object:
client.remote.multiply(7, 11);
client.remote.ping();

Use the accept method to deliver incoming server responses to the client to resolve request promises.

// Using setTimeout to simulate a future incoming message from the server
setTimeout(100, () => {
	const response = '{"jsonrpc":"2.0","result":77,"id":"2"}'; // Gets a response from the server somehow
	client.accept(response);
});

const result = await client.request('multiply', [7, 11]);

console.log(result); // Output: 77

Or using the proxy object:

const remote = client.remote;

const result = await remote.multiply(7, 11);

console.log(result); // Output: 77

Server and Client

The JsonRpcDualEngine class includes both a client and a server in it. It's useful in cases where you need bidirectional communication. The accept() method of the dual engine accepts both requests and responses.

import { JsonRpcDualEngine } from 'json-rpc-dual-engine';

const engine1 = new JsonRpcDualEngine({
	api: {
		getId() { return '1'; }
	}
});

const engine2 = new JsonRpcDualEngine({
	api: {
		getId() { return '2'; }
	}
});

engine1.onmessage = message => engine2.accept(message);
engine2.onmessage = message => engine1.accept(message);

console.log(await engine1.sendRequest('getId')); // Output: '2'
console.log(await engine2.sendRequest('getId')); // Output: '1'

WebSocket Example

On the server side:

import { JsonRpcServer } from 'json-rpc-dual-engine/server';
import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });
const engine = JsonRpcServer({
	api: {
		multiply(a, b) {
			return a * b;
		}
	}
});

wss.on('connection', ws => {
	ws.on('message', request => engine.accept(request)); // Messages from the client are handled by the engine
	engine.onresponse = response => ws.send(response); // Responses are sent to the client via websocket
});

On the client side:

import { JsonRpcClient } from 'json-rpc-dual-engine/client';
import WebSocket from 'ws';

const websocket = new WebSocket('ws://remote.example');
const engine = new JsonRpcClient();

engine.onrequest = request => websocket.send(request); // Requests are sent to the server via websocket
websocket.on('message', response => engine.accept(response)); // Responses from the server are handled by the engine

// Waits for connection before sending a message
await new Promise((resolve, reject) => {
	websocket.onopen = resolve;
	websocket.onerror = reject;
});

// Sends a json-rpc request through webscoket to the remote server and waits for the response
const result = await engine.remote.multiply(7, 11);

console.log(result); // Output: 77

Development Environment

Install Deps

npm install

Test

npm test

Coverage

npm run coverage

LICENSE

MIT