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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@shinka-rpc/core

v0.0.2

Published

Symmetric RPC bus. This page explains basic concepts only. [Documentation is here](https://shinka-rpc-js.readthedocs.io/latest/core/)

Readme

@shinka-rpc/core

Symmetric RPC bus. This page explains basic concepts only. Documentation is here

This package implements the main functionality of @shinka-rpc. Ironically the core know how to do everything but it is made so abstract that as is unable to do anything. So to make @shinka-rpc be able to do things, you have to pass the transport -- commonly very small function, returning 2 functions: send and close, and subscribing the bus instance to onMessage. Here you are able to implement the custom one (or more) or use any already existing:

Also there are some default serializers available:

The main advantage of @shinka-rpc is in re-using of the same core with all transports. And when you decided to build many RPC communication buses, your bundle would contain only one core

Symmetricity

It means both server and client may register request and event handlers, and then send requests and events to each other, and both may initialize connections

request and event

Scopes are separated. The difference is that request requires for the response and waits for it, and the event does not support response and does not wait for any feedback from other side -- shoot and forget

Usage

There are 2 scenarios: server and client usage. The only difference is server handles N clients. There are some strange cases: dedicated Worker or iframe. Who is a server and client if each of them are alone? Simple answer -- both of them are clients, it's OK to make RPC bus for client-client case

The first thing what we have to do is a bus initialization. I'll use as an example @shinka-rpc/shared-worker package

client initialization

import { ClientBus, FactoryClient } from "@shinka-rpc/core";
import { SharedWorker2FactoryData } from "@shinka-rpc/shared-worker/client";
import serializer from "@shinka-rpc/serializer-json";  // for example

const factory: FactoryClient<ClientBus> = async (bus) =>
  SharedWorker2FactoryData(
    new SharedWorker(new URL("./worker.ts", import.meta.url)),
    bus,
  );

export const bus = new ClientBus({ factory, serializer });

bus.start();

server initialization

// @ts-nocheck
declare let onconnect: (event: MessageEvent) => void;

import { ServerBus } from "@shinka-rpc/core";
import { SharedWorkerServer } from "@shinka-rpc/shared-worker/server";
import serializer from "@shinka-rpc/serializer-json";  // for example

export const server = new ServerBus({ serializer });

onconnect = SharedWorkerServer(server);

Register event and request handlers

Both server and client provide the same API:

  • 1-st handler arg: any payload. Use Object and Array to pass multiple args, and then unpack them

  • 2nd handler arg: thisArg

    • In client case it's ClientBus itself
    • In server case it's CommonBus -- client's representation
server.onRequest("load-meta", async () => {
  const response = await fetch("/meta.json", { cache: "no-store" });
  return await response.json();
});

let token: string | null = null;

server.onDataEvent("set-token", ([newToken]: [string]) => {
  token = newToken;
});

IMPORTANT: request handler can NOT return Promise. If you need to something asyncronous, just use async function as a handler

Call registered event and request handlers

Both server and client provide the same API:

type Meta = {};
const loadMeta = () => bus.request<Meta>("load-meta");  // returns Promise<Meta>
const setToken = (token: string) => bus.event("set-token", [token]);