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

rpc-stream

v2.1.2

Published

very simple rpc. use with any thing that has .pipe()

Downloads

838

Readme

#rpc-stream

RpcStream is a dead simple (75 loc) rpc system that works over any full-duplex text/byte/json stream. There's also a Python port, e.g. for cross-language RPC-over-SSH.

ports

rant

There are a bunch of people have already written node rpc systems, but most of them has done it right yet. My beef is that all these systems is that they are tightly coupled to, or wrapped around servers. what if I want to encrypt the messages? what if I want to send the messages over stdin/out, or over ssh? of write them to a temp file? there is one abstraction that matches all of these cases; the Stream

I should just be able to do this:

  REMOTE_SSH_STREAM           //<-- pipe data from a remote source
    .pipe(DECRYPT_STREAM)    //through some ('middleware') streams (ssh already encrypts, but I'm paranoid)
    .pipe(GUNZIP_STREAM)
    .pipe(RPC)               //<--- pipe the data through the RPC system.
    .pipe(GZIP_STREAM)
    .pipe(ENCYPT_STREAM)
    .pipe(REMOTE_SSH_STREAM)  //<-- and back to the remote

  //with something very similar on the other side.

RPC framework (AHEM! RPC MODULE!), you just worry about calling the right function, I'll decide where you go...

update: [email protected] now has first class streams, and you can pipe it where you like!

usage

var rpc = require('rpc-stream')

//create a server, that answers questions.
//pass in functions that may be called remotely.
var server = rpc({hello: function (name, cb) {
  cb(null, 'hello, '+name)
}})

//create a client, that asks questions.
var client = rpc()

//pipe rpc instances together!
client.pipe(server).pipe(client)

var remote = client.wrap(['hello'])
remote.hello('JIM', function (err, mess) {
  if(err) throw err
  console.log(mess)
})

over tcp

server

net.createServer(function(con) {
  // create one server per connection
  var server = rpc(/* ... */)
  server.pipe(con).pipe(server)
}).listen(3000))

client

var client = rpc()
var con = net.connect(3000)
client.pipe(con).pipe(client)

var remote = client.wrap(['hola'])
remote.hola('steve', function(err, res) {
  console.log(res)
})

rpc(methods, opts)

returns a RpcStream that will call methods when written to.

If opts.raw is set to true, JSON.stringify() is turned off and you just get a stream of objects, in case you want to do your own parsing/stringifying.

With opts.flattenError you can override the default method of converting errors to plain js objects. For example, to include non-enumerable properties too, pass:

{flattenError: function (err) {
  if(!(err instanceof Error)) return err
  var err2 = { message: err.message }
  var props = Object.getOwnPropertyNames(err)
  for(var k in err)
    err2[k] = err[k]
  return err2
}}

RpcStream#wrap(methodNames)

returns a wrapped object with the remote's methods. the client needs to already know the names of the methods. accepts a string, and array of strings, or a object. if it's an object, wrap will use the keys as the method names.

//create rpc around the fs module.
var fsrpc = rpc(require('fs'))
//pipe, etc

then, in another process...

var fsrpc = rpc()
//pipe, etc

//wrap, with the right method names.
var remoteFs = fsrpc.wrap(require('fs'))

remoteFs.mkdir('/tmp/whatever', function (err, dir) {
  //yay!  
})

now, the second process can call the fs module in the first process! wrap does not use the methods for anything. it just wants the names.

RpcStream#rpc(name, args, cb)

this gets invoked by wrap. but you could call it directly.

rpc().wrap('hello').hello(name, callback)
//is the same as
rpc().rpc('hello', [name], callback)

RpcStream#pipe

this is why we are here. read this and this

license

MIT/APACHE2