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

rx-txjs-publisher

v0.0.4

Published

A set of tools to build publication server of rx-txjs components

Downloads

5

Readme

Rx-TxJS Components Publication Client / Server Tools

What's New

version 0.0.4 Fix rx-txjs) job stuck bug with rotuepoint.

This package inlude a suite of tools helping to build publication server and client. Rx-TxJS implement the concept of decouping objects in process and between processes (services). The main idea of Rx-TxJS is calling an object by its unique name and send him a message (without any direct API activiation) in a similar fashion as RxJS does. The receive component is subscribe and act when those message arrive. You use a Components registry to find those objects living in process.

This suite of publication tools enable you to publish those Components over services / processes simlessly. Once Components has publish it able to call directly from one service to another in the excat same manager as they do in process. the caller has no idea where the Component is locate and doesn't need to handle those details. It just send him a message same as it does when the Components is defined locally in the service.

RoutePoint - is a an object use as a borker between the remote Components living in two different services.

See example project here typescript-publisher-example

Service side - Let see an example of Rx-TxJS's routepoint.

import { 
  TxMountPoint,
  TxRoutePointRegistry,
  TxRouteServiceTask,
  TxRouteServiceConfig
} from 'rx-txjs';

class R1Component {
  private mountpoint: TxMountPoint;

  // a routepoint configuration object
  private config: TxRouteServiceConfig = {
      host: 'localhost',
      port: 3100,
      method: 'get',
      service: 'sanity',
      route: 'save'
  };

  constructor() {  
    // create the routepoint, the regitry keep track of the routepoint instance by it's name
    this.mountpoint = TxRoutePointRegistry.instance.route('GITHUB::R1', this.config);

    // subscribe to upcoming calls from other services
    this.mountpoint.tasks().subscribe(
      (task: TxRouteServiceTask<any>) => {
        console.log('[R1Component::subscribe] subscribe called, task:', JSON.stringify(task.get(), undefined, 2));

        // send reply back to caller
        task.reply().next(new TxRouteServiceTask<any>({
          headers: {
            source: 'R1Component',
            token: '123456780ABCDEF'
          },
          response: {
            status: 200,
            type: 'json'
          }},
          {
            source: 'R1Component', status: "ok"
          }
        ));      
      });
  }

}
  1. GITHUB::R1: is the name of the component must be unique among ALL services.
  2. Headers: this goes to the HTTP header in the reqeust.
  3. reponse: this define how to send the response to the client.
  4. source: 'R1Component', status: "ok": any data object return back to client.

client-side - To use this routepoint internally or from another service use:

  // first create the client side routepoint. This is done once on initialization
  const config: TxRouteServiceConfig = {
    mode = 'client',    // I am on the client side
    host: 'localhost',  // <-- this is the host of other service
    port: 3100,         // <-- this is the port of other service
    method: 'get',      // <-- the method to use is 'get'
    service: 'sanity',  // the endpoint of other service is on /sanity/save
    route: 'save'
  }
  TxRoutePointRegistry.instance.create('GITHUB::R1', config);

  // then use it in where you want to get an already define routepoint on the client side
  const routepoint = TxRoutePointRegistry.instance.get('GITHUB::R1');

  // subscribe to reply from the receiver (the server)
  routepoint.subscribe(
    (task: TxTask<any>) => {
      console.log('[sendAndSubscribeServiceGet] got reply from service: ', JSON.stringify(task, undefined, 2));
    }
  );

  // make the call, send {source: 'back-client-main'}, {from: 'clientRoutePoint'} to the server
  const reply = routepoint.tasks().next(new TxRouteServiceTask<any>({source: 'back-client-main'}, {from: 'clientRoutePoint'}));

NOTE: So the task of the publication is create a routepoint on the client registry so you can use it on every point in the code without to define the above code on the client. The publication is do it for you. The task of the publciation is to make this two calles available:

  // the configration object as define on the server side
  const config: TxRouteServiceConfig = {
    ...
  }
  // the routepoint name as define on the server side
  TxRoutePointRegistry.instance.create('GITHUB::R1', config)

Publications Methods

  • Http Express: REST Api using standard express
  • System queues: Queue system like Kafka, RabbitMQ, Bull
  • Socket.IO / Web Sockets:

There are several possible ways of deploy services publication.

How to Configure My Code to Use Publication

Direct Services Publication using RESTApi

With this topology all services are directly communciating with all others (star topology). Each service send to all other its Components configuration. Lets see how it works.

To Initialize the publication you have to call to two methods:

  1. Define config object of your service like:
const config: PublisherRESTEndPointConfig = {
  name: 'service-a',    // my service name, must be unique 
  host: 'localhost',    // host address
  port: +PORT,          // port where your service listen to
  route: '/v1/publish'  // the route name of the publication middleware
}
  1. call to: javascript TxPublisherREST.instance.setApplication(app, config); // where app is the express application

This initiate the publication routes using your express application (middleware).

  1. Call to: javascript PublisherREST.instance.addEndPoint(host, port, '/v1/publisher'); // host, port, route of the other service

This will add an endpoint. Endpoint is the remote service you want to work with.

TxPublisherREST will send all you rotuepoints to others enpoints and receive from them there routepoints.

An example of a service may looks like that:

On startup each service initialize TxPublisherREST object as follow:

import * as express from 'express';
import { TxPublisherREST } from 'rx-txjs-publisher/route';

const app = express();

/**
 * init the RESTApi publisher under '/v1/publisher' route on my side
 * @param host  - my hostname / IP
 * @param port  - port number of my service
 * @param app   - express application 
 * @param '/v1/publisher' - the path where all services communicating 
 */
const config: PublisherRESTEndPointConfig = {
  name: 'service-a',    // my service name, must be unique 
  host: 'localhost',    // host address
  port: +PORT,          // port where your service listen to
  route: '/v1/publish'  // the route name of the publication middleware
}

// inititate the publication.
TxPublisherREST.instance.setApplication(app, config);

// add a bunch of other endpoint on other services need to publish from / to
TxPublisherREST.instance.addEndPoint(host, port, '/v1/publisher');
.
.
.
TxPublisherREST.instance.addEndPoint(host, port, '/v1/publisher');

// create new routepoint objects
new R1Componet();
new R2Componet();
new R3Componet();
  • TxPublisherREST.instance.setApplication() - this method init the publisher middleware. Every time when a Component init its rotuepoint it send the routepoint configuration data to all other services as define in by TxPublisherREST.instance.addEndPoint() calls.

  • TxPublisherREST.instance.addEndPoint() - add end point of other service need to send the routepoint configuration paramaerts.

After that you can call components "living" in other services.

Discovery - find which service define a routepoint

when you call to TxRoutePointRegistry.instance.get('some-routepoint-name') but TxRoutePointRegistry can't find in it's local cache it use the help PblisherREST object to find which endpoint has this routepoint. PblisherREST send a discovery message to all its endpoints. Once it find the desire routepoint it save in the cache for later use.

Behind the scene of PublisherREST

PublisherREST has two main functionalities. One is to publish all routepoints to other endpoints and second to get from other endpoints their routepoints. During startup is contantly keep trying until it fullfill both two.