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

@cisl/io

v2.0.0

Published

A framework for building distributed applications

Downloads

51

Readme

@cisl/io

A framework for building distributed applications and the coolest of Jupiter's moons.

If coming from @cel/io, please see the migration guide.

Installation

npm install @cisl/io

Usage

NodeJS

const io = require('@cisl/io')();
// or through instantation of a new class
const Io = require('@cisl/io/io').Io;
const io = new Io();

TypeScript:

import io from '@cisl/io';
// or through instantation of a new class
import { Io } from '@cisl/io/io';
const otherIo = new Io();

Configuration

The configuration for applications using @cisl/io should be stored in the cog.json file. This is then internally stored as a JSON object at io.config.

API

Core

The core of Io, which is always available consists of the following methods:

generateUuid(): string

This function when calls, returns a v4 uuid string with dashes.

RabbitMQ

RabbitMQ requires the rabbit value to be set, where true will use the defaults below. Any field not set will use these defaults:

{
  "rabbit": {
    "url": "localhost",
    "username": "guest",
    "password": "guest",
    "exchange": "amq.topic",
    "vhost": "/"
  }
}

If you wish to enable SSL to communicate with RabbitMQ, you will need to set rabbit.ssl to true, and then define the following keys to point at filenames to read in:

  • cert
  • key
  • ca

And optionally define a passphrase to use for the key file.

You can access the RabbitMQ object by using io.rabbit.

io.rabbit will also attempt to connect to the management plugin to allow monitoring queue status. By default, it will use the same details as the regular RabbitMQ URL to connect and assumes port 15671 for non-SSL and 15672 for SSL. If you wish to use a different detail, you can append mgmt_ to any of the same variables as used for above. The full list is:

interface RabbitOptions {
  // ...

  mgmtSsl?: boolean;
  mgmtUrl?: string;
  mgmtHostname?: string;
  mgmtPort?: number;
  mgmtUsername?: string;
  mgmtPassword?: string;
}

If you specify mgmtUrl, then it will only use that URL verbatim. Otherwise, it'll use the other parts to build the fully qualified URL to use. For any value omitted, it'll default to what was used for the regular connection details.

Usage

// where Message is an interface from https://www.squaremobius.net/amqp.node/
interface RabbitMessage extends Omit<Message, 'content'> {
  content: Buffer | string | number | object;
  fields: MessageFields;
  properties: MessageProperties;
}

type ReplyCallback = (content: Error | Buffer | string | number | object) => void;
type RpcReplyCallback = (message: RabbitMessage, reply: ReplyCallback, awkFunc?: () => void) => void;
type PublishCallback = (message: RabbitMessage) => void;

// Publish to a RabbitMQ topic on the configured exchange
io.rabbit.publishTopic(topic: string, content: Buffer | string | number | object, options: amqplib.Options.Publish = {}): Promise<boolean>

// Listen to a topic for any new content
io.rabbit.onTopic(topic: string, handler: PublishCallback, exchange?: string): Promise<Replies.Consume>

// Publish to a RPC queue, expecting a callback through the promise
io.rabbit.publishRpc(queue_name: string, content: Buffer | string | number | object, options: amqplib.Options.Publish = {}): Promise<Response>

// Listen on a RPC queue, sending content back through handler
io.rabbit.onRpc(queue_name: string, handler: RpcReplyCallback, exclusive = true): Promise<void>

// Get a list of all queues
io.rabbit.getQueues(): Promise<unknown>

// Listen for any queue creations
io.rabbit.onQueueCreated(handler: (properties: amqplib.MessageProperties) => void): void
// Listen for any queue deletions
io.rabbit.onQueueDeleted(handler: (properties: amqplib.MessageProperties) => void): void

See amqplib for acceptable values for the options argument.

Publishing / Receiving and Content-Types

For publishTopic and publishRpc allows taking in a variety of types, and internally parses it to a Buffer and setting the appropriate content-type before sending it along RabbitMQ. For example, calling:

io.rabbit.publishTopic('test', { test: true });

Will encode the JSON array into a Buffer and set the content-type appropriately to application/json.

Conversely, for onTopic and onRpc will attempt to parse the content off RabbitMQ using the content-type. If no content-type is available or unrecognized, then it will return a Buffer for the content, whereas if the content-type is application/json, then content will be a JSON object. See the table below for correspondence between content-type and the expected type of Response.content.

Finally, if you wish to override the automatic content-type selection on the publish functions, you can pass in one in the options value. Io will still handle automatic conversion of the value into a Buffer.

| content-type | value | | ------------------------ | ------ | | text/string | string | | text/number | number | | application/json | JSON | | application/octet-stream | Buffer | | other | Buffer |

Content-Type

For publishing content, if a content-type is not specified and the content is not a Buffer, then Io will assume that it can be run through JSON.stringify and will set the content-type to application/json automatically. On receving content, if the content-type is set to application/json, then Io will automatically run JSON.parse and return that content, else it will return the Buffer object for the user to manually deal with.

Queue Names

When subscribing to events, you can include in topic name wildcards * and #. * substitues one word, and # substitues multiple words. For example, transcript.result.* subscribes to transcript.result.final and transcript.result.interim, whereas transcript.# subscribes to transcript.result.final, transcript.result.interim, and transcript.command.

Redis

@cisl/io provides a shallow wrapper around the ioredis library, such that io.redis returns an instantiated and connected to ioredis.Client instance. See its documentation for additional details on using it.

{
  "redis": {
    "host": "localhost",
    "port": 6379,
    "db": 0
  }
}

The above are the defaults that will be used if any are missing. See ioredis#options for the full list of options you can use when connecting the client.

Usage

io.redis;
console.log(io.redis.getBuiltinCommands());

Mongo

@cisl/io provides a shallow wrapper around the mongoose library, along with several useful utility functions for interacting with it.

To configure to the default setup, use mongo: true, or you can configure it for your needs using the following settings:

{
  "mongo": {
    "host": "localhost",
    "port": 27017,
    "dbname": "cais"
  }
}

Usage

io.mongo.mongoose: mongoose.Mongoose;
io.mongo.model<T>(name: string, schema: mongoose.Schema): Model<T>;
io.mongo.disconnect();

Registering Plugins

To extend the behavior of @cisl/io, you can register plugins. To register a plugin, you need to only import the file. As part of loading it, it will register itself with @cisl/io and any existing Io instances you may have created.

For example:

const io = require('@cisl/io')();
require('@cisl/io-speaker');
require('@cisl/io-transcript');

io.speaker.speak(/* ... */);
io.transcript.tagChannel(/* ... */);

License

MIT License

Icon Attribution

Moon by MarkieAnn Packer from the Noun Project