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 🙏

© 2024 – Pkg Stats / Ryan Hefner

push-rpc

v1.0.9

Published

- Data-driven apps with or without server-initiated updates - OCPP-J clients and servers - IoT devices connecting to servers - General client/server apps using Websockets for communications

Downloads

4

Readme

A framework for organizing bidirectional client-server communication based on JSON and Websockets.

Client establishes Websocket connection to server and then client and server exchange JSON-encoded packets.

JSON-packets forms high-level protocol, based on WAMP. Being based on WAMP, Push-RPC protocol doesn't strictly conforms to it. Instead it conforms to OCPP-J RPC Framework. More precisely, Push-RPC protocol is a superset of OCPP-J RPC protocol, with additional PUSH capabilities.

Push-RPC allows you to:

  • create client-initiated connections between client and server
  • bi-directionally invoke remote methods on server and client
  • subscribe client for server-side events
  • auto-reconnect with subscription refresh.
  • helpers for wrapping communications into handy JS (or TypeScript) objects.

Possible Applications

  • Data-driven apps with or without server-initiated updates
  • OCPP-J clients and servers
  • IoT devices connecting to servers
  • General client/server apps using Websockets for communications

Getting Started

Installation

yarn add typescript-push-rpc

For the server, you will also need

yarn add ws

You can use standard browser WebSockets on the client, or also use ws npm package.

Example code (slightly outdated)

shared.ts:

import {Topic} from "../src/index"

export interface Services {
  todo: TodoService
}

export interface TodoService {
  addTodo({text}): Promise<void>
  todos: Topic<{}, Todo[]>
}

export interface Todo {
  id: string
  text: string
  status: "open" | "closed"
}

server.ts:

import {createRpcServer, ServerTopicImpl} from "../src/index"
import {Services, TodoService, Todo} from "./shared"
import * as WebSocket from "ws"

let storage: Todo[] = []

class TodoServiceImpl implements TodoService {
  async addTodo({text}) {
    storage.push({
      id: "" + Math.random(),
      text,
      status: "open",
    })

    console.log("New todo item added")

    this.todos.trigger({})
  }

  todos = new ServerTopicImpl(async () => storage)
}

const services: Services = {
  todo: new TodoServiceImpl(),
}

const rpcWebsocketServer = new WebSocket.Server({port: 5555})
createRpcServer(services, rpcWebsocketServer)

console.log("RPC Server started at ws://localhost:5555")

client.ts:

import * as WebSocket from "ws"
import {Services} from "./shared"
import {createRpcClient} from "../src"

(async () => {
  const services: Services = await createRpcClient({
    level: 1,
    createWebSocket: () => new WebSocket("ws://localhost:5555")
  })

  console.log("Client connected")

  services.todo.todos.subscribe({}, (todos) => {
    console.log("Got todo items", todos)
  })

  await services.todo.addTodo({text: "Buy groceries"})
})()

Run server.ts and then client.ts.

Server will send empty todo list on client connecting and then will send updated list on change.

Goodies

Using TypeScript to define contract between client and server

The framework allows you to define and consume your API using TypeScript interface. The interface definition could be shared between server and client code bases, providing a type-safe contract between server and client.

Also

  • Generating client and server RPC proxies based on zero-config TS interface.
  • JSON bodies auto-parsing with Date revival.
  • Supported client envs: Node.JS (with isomorphic-fetch), browser, react-native(see notes).

API

TBD

WS protocol details

You can use this information to implement Typescrip-Push-Rpc protocol in different languages.

TBD

Roadmap

  • File upload support via multipart encoding (uses koa-multer under the hood).
  • Binary data download.
  • Generation of OpenAPI (Swagger) YAMLs with API description

FAQ

How to add path to websockets (routing)

Using with React-Native (Revised, could be outdated!)

For generating clients ES6 Proxy is used. However, React-Native doesn't support ES6 proxy on some devices, see this RN Issue. And no polyfills could exist that will handle dynamic properties. So for React Native you should explicitly list your interface operations:

export let backend: Backend = createClient(url, { ... }, 
    [ "login", "resetPassword", etc ]
)