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

@plmtest/cosmos-service-builder

v1.0.26

Published

Package that exposes class instances to facilitate service creation

Readme

PLM Fleet Service Builder

This package provides abstractions for creating micro-services.

It bundles common utilities and middlewares for web services serving REST and/or gRPC APIs.

Usage

Starting an Express Server

const { ExpressServer } = require('@plmtest/cosmos-service-builder')

new ExpressServer({
  configuration: {
    port: config.APP_PORT,
    adminPort: config.ADMIN_PORT
  },
  logger: config.LoggerConfig
})
  .start()
  .addServerMetrics(config.MonitoringConfig)
  .addProbes({ readinessProbe, livenessProbe })
  .asWebService()
  .withSecuredEndpoints({
    security: {
      jwksUri: config.JWKS_URI
    }
  })
  .addHeaderMiddleware()
  .addRequestHandlerMiddleware()
  .addRoutes('v1', routes, { remotes, services })
  .addResponseHandlerMiddleware()
  .stop()

This starts a express server with the following:

  • The server exposes two ports:
    • config.APP_PORT which is the application port providing all application endpoints, typically port 8080
    • config.ADMIN_PORT which is the admin port providing additional endpoints like /metrics, /readz or /healthz, typically port 8081
  • The service will provide a /metrics endpoint that exposes Prometheus metrics for monitoring purposes.
  • The functions readinessProbe and livenessProbe that are passed into addProbes are executed when the probe endpoints /healthz and /readz are called. There are typically configured as endpoints for Kubernetes liveness and readiness probes.
  • Requests to all endpoints of the service requre a valid OAuth access token (JWT). It will be checked using config.JWKS_URI.
  • All routes from routes are exposed as endpoints with the prefix v1. routes is expected to be a map of router functions. The map's Keys will be used as context paths.
  • The service will gracefully shut down once it receives any KILL signal.

Starting a gRPC Server

const { GRPCServer } = require('@plmtest/cosmos-service-builder')

new GRPCServer({
  configuration: {
    port: config.GRPC_PORT,
    host: config.GRPC_HOST
  },
  logger: config.LoggerConfig
})
  .addPackages({ protoPaths }, { servicePackages, params: { remotes, services } })
  .start()
  .stop()

This starts a gRPC server on port GRPC_PORT at host GRPC_HOST, typically 0.0.0.0:50051.

Adding gRPC Services from Protobuf

Before the server is started using start(), services or packages need to be added to the server. They originate from protobuf definition and refer to implementation in the service.

Three different ways to add services are available:

  • addService()
  • addPackage()
  • addPackages()

All three functions take two parameter object arguments. The first one refers to the protobuf, while the second refers to the service implementation(s) and arguments to be passed into the constructor.

addService() - Adding an individual service

Using addService() offers the most flexibility adding a service to the gRPC server as almost everything is explicitly defined. Nevertheless, it is recommended to follow the conventions mentioned below.

addService({
  protoPackage: 'sample.hello',
  protoService: 'HelloService',
  protoPath: protoPaths.sample // imported from a protobuf package
}, {
  serviceClass: servicePackages.sample.hello.HelloService, // class of the service implementation
  params: { remotes, models }
})
  • protoPackage and protoService should match what is defined in the reference protobuf file under protoPath.
  • serviceClass is a reference to the constructor of the grPC service implementation, which will be instantiated using params.
  • As an alternative to serviceClass a service instance can be passed in as service. params will be ignored in this case.
addPackage() - Adding an entire package

This is a convenience function that adds all services from a protobuf file and package to the gRPC server. In order to make this work as expected, it is important to follow the conventiones described below.

addPackage({
  protoPath: protoPaths.sample // imported from a protobuf package
}, {
  servicePackage: servicePackages.sample, // map of the service class implementations
  params: { remotes, models }
})
  • servicePackage is a (nested) map of packages and service class implementations. Sub-packages defined in the protobuf file are expected to exist as paths in that map.
addPackages() - Adding all defined packages

This is another convenience function that adds all packages that match the provided protobuf files to the gRPC server. In order to make this work as expected, it is important to follow the conventiones described below.

addPackages({
  protoPaths // imported from a protobuf package
}, {
  servicePackages, // map of the service class implementations
  params: { remotes, models }
})

Internally, this function relies on addPackage().

Implementing gRPC Services

The implementation of gRPC services relies on a set of assumptions or conventions.

A gRPC service:

  • is implemented as a class with a single-argument constructor
  • implements all functions exactly as they are defined in the associated protobuf file
  • has the same name as the service defined in the associated protobuf file
  • is located in a directory that matches the protobuf package, e.g., sample.hello.HelloService is implemented in sample/hello/HelloService.js

Moreover, protobuf packages are expected to export a map of proto paths, e.g.:

const baseProtoUrl = `${__dirname}/protos`

module.exports = {
  sample: `${baseProtoUrl}/sample.proto`
}

Furthermore, the key (sample) is expected to match the name of the root package.

Setting up a gRPC Client

const { GRPCClient } = require('@plmtest/cosmos-service-builder')
const protoPaths = require('@plmtest/sample-protobufs')

const grpcClients = {
  ...new GRPCClient({
    protoPath: protoPaths.sample,
    logger: config.LoggerConfig
  }).connect('127.0.0.1:50051') // we connect to ourselves
}

This adds gRPC clients to the grpcClients object. Packages and services defined in the protobuf file will be available pased on there package structure.

The service defined in the protobuf below can be called as follows:

package sample.hello;

service HelloService {
  rpc sayHello (Empty) returns (SayHelloResponse) {
  }
}
const someHelloFunction = async () => {
  const response = await grcClients.sample.hello.HelloService.sayHelloAsync({})
}

Note that the gRPC client will use bluebird to promisify the gRPC service methods. So it will return a promise-based gRPC service call instead of callbacks.

As you can see in the example, this will append 'Async' to all the corresponding proto methods, i.e, sayHello on the proto definition becomes sayHelloAsync when you want to use the gRPC client to call that service.