@pubkeeper/client
TypeScript icon, indicating that this package has built-in type declarations

4.0.7 • Public • Published

Pubkeeper Client

@pubkeeper/client enables web browsers to join, consume, and produce content on a Pubkeeper network.

Concepts & Terms

  • Brew : A protocol/method of delivery, e.g. WebSocket, SocketIO, WebRTC, HTTP
  • Brewer : An object bound to a specific topic that accepts a data transports it to matched patrons.
  • Patron : A consumer bound to one or more topics, it receives data from matched brewers.

Installation

In a browser:

<script src="pubkeeper-client.js"></script>

Using npm:

$ npm install --save @pubkeeper/client

Then, load using ES5 require() syntax…

var PubkeeperClient = require('@pubkeeper/client').PubkeeperClient;

…or with ES2015+ import syntax:

import { PubkeeperClient } from '@pubkeeper/client';

Basic Syntax

Client Configuration

import { PubkeeperClient } from '@pubkeeper/client';
import { WebSocketBrew } from '@pubkeeper/brew-websocket';
import { PubkeeperAesCbcCrypto } from '@pubkeeper/crypto-cjs-aes-cbc';

// Create a client
const client = new PubkeeperClient({
  server: 'wss://192.168.100.191:9898/ws',
  jwt: "[your JWT]",
  crypto: new Map([
    PubkeeperAesCbcCrypto,
  ]),
  brews: [
    new WebSocketBrew({
      brewerConfig: {
        hostname: '192.168.100.191',
        port: 8000,
        secure: true,
      },
    }),
  ],
});

client.connect();

Note: This client is the core pubkeeper client, as such it does not include any crypto or brews. If you want a pre-packaged version suitable for general usage see @pubkeeper/browser-client

Brewing Setup

To produce data into the Pubkeeper network you will need to create a brewer. The example below will setup a Brewer with the topic of topic.information

client.addBrewer('topic.information', (brewer) => {
  // brewer has been *matched* by pubkeeper, i.e. there is
  // at least one patron of this topic.
  let counter = 0;

  const id = setInterval(() => {
    brewer.brewJSON({ counter });
    counter += 1;
  }, 1000);

  return function teardown() {
    // teardown function will be called when there are
    // _no_ more patrons or this brewer has been removed.
    clearInterval(id);
  };
});

Patron Setup

To listen to someone who is brewing information, you need to subscribe to the topic, and configure a callback to occur when there is data available for processing.

client.addPatron('weather.*', (patron) => {
  // patron has been *matched* by pubkeeper, i.e. there is
  // at least one brewer of this topic.
  function handler(bytes, meta) {
    console.log(meta.from, meta.topic, patron.id, bytes);
  };

  patron.on('message', handler);

  return function teardown() {
    // teardown function will be called when there are
    // _no_ more brewers or this patron has been removed.
    patron.off('message', handler);
  };
});

Brewer/Patron Connections

The Patron message event is always fired with a Uint8Array as data, no matter which brew*() method was called on the brewing side. You need to handle parsing/casting those bytes.

For instance, given a brewer:

client.addBrewer('tick', (b) => {
  let id, count = 0;
  (function tick() {
    id = setTimeout(tick, 1000);
    b.brewJSON({ count });
  })();
  return () => { clearTimeout(id); };
});

Then on the patron side, it would look like this;

client.addPatron('tick', (p) => {
  const handler = (bytes) => {
    const text = new TextDecoder().decode(bytes);
    const value = JSON.parse(text);
    console.log(value.count);
  };
  p.on('message', handler);
  return () => { p.off('message', handler); };
});

NOTE This will be resolved in future versions of the protocol.

State Change Events

Brewers and Patrons will be notified when thier couterparts are added or removed:

client.addBrewer('topic.information', (brewer) => {
  const handleAdded = ({ id, topic }) => {
    console.log('patron (%s) added', id);
  };

  const handleRemoved = ({ id }) => {
    console.log('patron (%s) removed', id);
  };

  // setup
  brewer.on('added', handleAdded);
  brewer.on('removed', handleRemoved);

  return function teardown() {
    // cleanup
    brewer.off('added', handleAdded);
    brewer.off('removed', handleRemoved);
  };
});

PubkeeperClient Class

The PubkeeperClient manages the connection to a pubkeeper server.

new PubkeeperClient(options)

Name Type Description
options ClientOptions The options for this pubkeeper client
ClientOptions : object

These options can be given to a PubkeeperClient to customize its behavior.

Name Type Default Description
server string - Websocket URL of the pubkeeper server
jwt string - Auth token for the pubkeeper server
brews Array<Brew> [] Supported brews of this client
crypto Map<*,Crypto> new Map Supported crypto mappings for this client
protocols Map<*,Protocol> new Map Supported protocol mappings for this client. Defaults to the legacy protocol
maxRetries number Infinity Maximum number of connection retries
maxTimeout number 10000 Maximum timeout between retries (in milliseconds)
Examples

Using ES2015 Promise:

const client = new PubkeeperClient(config)

client.connect().then(() => {
  console.log('ready');
});

Using ES2017 async/await:

(async () => {
  const client = new PubkeeperClient(config)
  await client.connect();
  console.log('ready');
})();

Members

.status : string

Returns the status of this client. Can be one of the following:

Value Description
'connecting' Attempting to connect.
'connected' Connected
'reconnecting' Has lost the connection, and has queued a reconnection attempt.
'disconnected' Disconnected
'dead' Given up retrying to connect

Methods

.connect({ wait = true } = {}) : Promise?

Connect to the configured pubkeeper server. If { wait: true } is specified, this function will return a Promise that will be resolved when the connection to the pubkeeper server has been finalized. Passing { wait: false } will immediately return undefined and the server may or may not be connected yet.


.disconnect()

Disconnect from the server.


.addBrewer(topic[,[ options,] matched]) : Brewer

Create a new brewer of topic.

Name Type Description
topic string The topic
options BrewerOptions
matched Function Callback that is invoked when the brewer has been matched with a patron
BrewerOptions : object

These options can be given to the PubkeeperClient#addBrewer method to customize the brewers behavior.

Name Type Default Description
autoRemoveListeners boolean false Automatically remove all event listeners on unmatch
brews Array<(string|Brew)> - A subset of brews to use for this brewer, defaults to all registered brews.
id string - The UUID of this brewer, defaults to a random UUIDv4
waitForBrews (number|boolean) 250 The maximum wait time to wait when brewing data for brew connections to stablize.
Examples

Using the matched callback:

client.addBrewer('topic', (brewer) => {
  brewer.brewText('somebody is out there!');
});

With extended options:

// Do not wait for brew connections to stablize before sending.
client.addBrewer(
  'topic',
  { waitForBrews: false },
  (brewer) => {
    brewer.brewText('somebody is out there!');
  },
);

Managing resources with teardown function:

client.addBrewer(
  'device.motion',
  (brewer) => {
    const handler = ({ acceleration }) => {
      brewer.brewJSON(acceleration);
    };
    window.addEventListener('devicemotion', handler);
    return () => {
      window.removeEventListener('devicemotion', handler);
    };
  },
);

.removeBrewer(brewer)

Remove a brewer from this client.

Examples
const ref = client.addBrewer('topic', matchedFn);
/* ...later */
client.removeBrewer(ref);

.addPatron(topic[,[ options,] matched]) : Patron

Create a new patron of topic.

Name Type Description
topic string The topic
options PatronOptions
matched Function Callback that is invoked when the patron has been matched with a brewer
PatronOptions : object

These options can be given to the PubkeeperClient#addPatron method to customize the patrons behavior.

Name Type Default Description
autoRemoveListeners boolean false Automatically remove all event listeners on unmatch
brews Array<(string|Brew)> - A subset of brews to use for this patron, defaults to all registered brews.
id string - The UUID of this patron, defaults to a random UUIDv4
Examples

Using the matched callback:

client.addBrewer('topic', (patron) => {
  const handler = (data, meta) => { /* process data */ };
  patron.on('message', hanlder);
  return () => { patron.off('message', handler); };
});

.removePatron(brewer)

Remove a patron from this client.

Examples
const ref = client.addPatron('topic', matchedFn);
/* ...later */
client.removePatron(ref);

Brewer Class

A brewer is a publisher of information in a pubkeeper system.

Members

.id : string

the uuid of this brewer


.brews : Array<string>?

the subset of brew names that this brewer is using.


.topic : string

the topic this brewer is bound to


.count : number

current count of matched patrons


.isMatched : boolean

Is the brewer currently matched with any patrons

Methods

.brew(bytes[, options]) : Promise

Publish binary data to a brewer.

Name Type Description
bytes (Uint8Array|Uint8ClampedArray) Binary data to brew
options object
options.waitForBrews number? Override the brewers config

.brewText(text[, options]) : Promise

Publish text as a UTF-8 encoded byte array.

Name Type Description
text string text to brew
options object
options.waitForBrews number? Override the brewers config

.brewJSON(value[, options]) : Promise

Publish value using JSON.stringify.

Name Type Description
value * value to serialize and brew
options object
options.waitForBrews number? Override the brewers config

.on(event, fn[, context]) : this
.addListener(event, fn[, context]) : this

Add a listener for a given event.


.off(event, fn[, context[, once]]) : this
.removeListener(event, fn[, context[, once]]) : this

Remove the listeners of a given event.

Events

added

Fired when a matched patron is added.

Name Type Description
e object
e.id string UUID of the added patron
e.topic string topic of the brewer

removed

Fired when a matched patron is removed.

Name Type Description
e object
e.id string UUID of the removed patron

Patron Class

A patron is a subscriber of information in a pubkeeper system.

Members

.id : string

the uuid of this patron


.brews : Array<string>?

the subset of brew names that this patron is using.


.topic : string

the topic this patron is bound to


.count : number

current count of matched brewers


.isMatched : boolean

Is the patron currently matched with any brewers

Methods

.on(event, fn[, context]) : this
.addListener(event, fn[, context]) : this

Add a listener for a given event.


.off(event, fn[, context[, once]]) : this
.removeListener(event, fn[, context[, once]]) : this

Remove the listeners of a given event.

Events

added

Fired when a matched brewer is added.

Name Type Description
e object
e.id string UUID of the added brewer
e.topic string topic of the brewer

removed

Fired when a matched brewer is removed.

Name Type Description
e object
e.id string UUID of the removed brewer

message

Fired when a message is recieved from a brewer.

Name Type Description
data Uint8Array The binary data from the brewer
meta object
meta.topic string topic of the brewer that brewed this data
meta.from string UUID of the brewer that brewed this data

Readme

Keywords

none

Package Sidebar

Install

npm i @pubkeeper/client

Weekly Downloads

7

Version

4.0.7

License

UNLICENSED

Unpacked Size

560 kB

Total Files

32

Last publish

Collaborators

  • 32bitkid
  • mattdodge