oak-tools

0.5.7 • Public • Published

oak-tools

Helpful utilities for developing oak applications

npm Circle CI build status Coverage Status license Standard - JavaScript Style Guide

nodei.co

Install

npm install --save oak-tools

Documentation

Head on over to the documentation page!

Usage

oak-tools consists of a few helpful utility methods. Everything exposed from the module is a Class and needs to be constructed using new, except the logger

logger()

The logger is based off pino and has nearly the same same option parameters. The following example are the default options.

const { logger } = require('oak-tools')
let log = logger({
  // these are the default properties
  level: 'info',
  stream: process.stdout,
  pretty: false
})
log.info('sup')
log.error({
  err: new Error('crap...')
})
log.debug({
  msg: 'debug message here',
  now: Date.now()
})
 

server(type)

The server is extended from a good 'ol EventEmitter2. Head here for full documentation on the server class

const msgpack = require('msgpack5')()
const Server = require('oak-tools').server('websocket')
 
// all these options are, well... optional
let server = new Server({
  // these are the default properties
  port: 9500,
  host: 'localhost',
  serializer: { encode, decode } = msgpack
})
 
server
  .on('error', function (err) {
    console.error('* client error', err)
  })
  .on('connection', function (ID) {
    console.log('* client connection: ', ID)
  })
  .on('reconnect', function (ID) {
    console.log('* client reconnect: ', ID)
  })
  .on('close', function (ID) {
    console.log('* client closed', ID)
  })
  .on('who.is.the.man.now', function () {
    server.pub('heres.who', {
      answer: 'you are. http://www.yourethemannowdog.com/'
    })
  })

client(type)

The client API is similar to server, but it has both a sub and a pub method.

const { join } = require('path')
 
let Client = require(join(__dirname, '..')).client('websocket')
 
let client = new Client({
  id: 'sean connery' // defaults to random UUID
})
 
client.on('ready', function () {
  console.log('* client is connected')
  client
    .on('heres.who', function ({ answer }) {
      console.log(answer)
    })
    .pub('who.is.the.man.now')
})

Message Rationale & Flow

The goal of the server/client is to wrap up all the higher level messaging operations to be more protocol agnostic (as well as non-repetitive). This means we have a couple more steps than a normal TCP or WebSocket flow:

Client -> Server

  1. Client publishes on a namespace

    client > pub('foo.bar', { my: 'message' })

  2. The namespace and message get split into an flat array, where the last item is the message

    client > outbound message [ 'foo', 'bar', { my: 'message' } ]

  3. Payload gets encoded by the client

    client > encode(array) // <Buffer a5 68 65 6c 6c 6f>

  4. Client sends encoded message to the server

    client > send(payload)

  5. Server receives payload Buffer

    server > on('message', decode)

  6. Server receives and unpacks the payload

    server > decode(payload) // our array

  7. Server reconstructs the array, and emits the message

    server > emit('foo.bar', { my: 'message' })

Server -> Client(s)

  1. Client sends a subscription message to the server, through its binding

    client > on('foo.*', handler)

  2. Server receives a subscription event from the client

    server > on('_sub') // remember client wants 'foo.*' messages

    Time passes...

  3. Server sends an event to all clients that subscribed

    server > pub('foo.baz', { my: 'message' }) // matches anyone who sent _sub to foo.*

  4. Encode and write the same way the client does to each socket

    server > each connections send(payload)

  5. Client receives payload, unpacks, and emits it

    client > on('foo.*', fn(data)) // this.event === foo.baz

Serializer

On both server and client, encoder and decoder to pass messages. The serializer consists of the encoding and decoding methods to use against payloads. By default, we use msgpack5, but doing something as simple as this will work:

new clientOrServer({
  serializer: {
    encode: JSON.stringify,
    decode: JSON.parse
  }
})

Dependencies

Package Version Dev
eventemitter2 ~4.1.0
mdns-js ~0.5.3
minimatch ~3.0.3
msgpack5 ~3.4.1
pino ~4.4.0
safe-buffer ~5.1.0
swagger-client ~3.0.2
uuid ~3.0.1
ws ~3.0.0
ws-heartbeats ~1.0.0
coveralls ~2.13.0
docdash ~0.4.0
istanbul ~0.4.5
jsdoc ~3.5.0
node-readme ~0.1.9
standard ~10.0.0
tap-difflet ~0.7.0
tape ~4.7.0

Contributing

Contributions welcome; Please submit all pull requests against the master branch. If your pull request contains patches or features, you should include relevant unit tests. Thanks!

Authors

License

Readme

Keywords

Package Sidebar

Install

npm i oak-tools

Weekly Downloads

13

Version

0.5.7

License

Apache-2.0

Unpacked Size

44 kB

Total Files

16

Last publish

Collaborators

  • rjoffray
  • nirziv
  • nucleardreamer