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

liquid-tap

v0.3.6

Published

Liquid Websocket API Client

Downloads

113

Readme

LiquidTap Javascript Client

To manage API tokens, refer to: https://app.liquid.com/settings/api-tokens

To learn more about Liquid Api token management, see the help links below: https://help.liquid.com/connect-to-liquid-via-api

Links

Events Authentication [Troubleshooting] (#troubleshooting) [Contributing] (#contributing)

Quick Start

Install via npm or yarn:

npm install liquid-tap
yarn add liquid-tap

OR Include the library:

<script src="../dist/liquid-tap.js"></script>
import { TapClient } from "liquid-tap";

const tap = new TapClient();
const public_channel = tap.subscribe("product_cash_btcsgd_7");
public_channel.bind("updated", function(data) {
  console.log("product_cash_btcsgd_7 has been updated", data);
});

Events

| Event | Payload | Description | | ------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | | connected | { reconnect: boolean } | Fires on successful connection. Contains a boolean indicating whether this was an automatic reconnection. | | disconnected | n/a | Fires on disconnect. | | unavailable | n/a | Fires when a connection is unavailable for any reason. | | tick_received | { event: string, data: any, channel?: string } | Fires on every websocket event. Contains the entire websocket payload. | | authenticated | n/a | Fires when the websocket has successfully authenticated | | authentication_failed | { message: string, attempts: number } | Fires when authentication has failed. Contains a message from the server and the number of authentication attempts. | | authentication_aborted | { attempts: number } | Fires when the maximum number of automatic authentication retries is reached. Contains the number of attempts. |

Binding to events

Callbacks

import { TapClient }, { CLIENT_EVENTS } from 'liquid-js'

var tap = new TapClient();
tap.bind(CLIENT_EVENTS.CONNECTED, function () {
  console.log('Connected!');
});
tap.bind(CLIENT_EVENTS.AUTH_SUCCESS, function () {
  console.log('Authenticated!');
});
tap.bind(CLIENT_EVENTS.AUTH_FAILURE, function () {
  console.log('Authentication Failed!');
});

Promises

var tap = new TapClient();
tap.bind(CLIENT_EVENTS.CONNECTED).then(() => {
  console.log("Connected!");
});
tap.bind(CLIENT_EVENTS.AUTH_SUCCESS).then(() => {
  console.log("Authenticated!");
});
tap.bind(CLIENT_EVENTS.AUTH_FAILURE).then(() => {
  console.log("Authentication Failed!");
});

Options

| Key | Type | Default | Description | | ----------------------- | ---------------------- | ------------------- | ------------------------------------------------------------------------------------- | | wsHost | string | 'tap.liquid.com' | Tap WS host to connect to. | | wsPort | number | 433 | Port to connect to. | | wssPort | number | 433 | SSL Port to connect to. | | useTls | boolean | true | Should connect using SSL. | | auth | AuthType (see below) | null | Authentication information. See below. | | appId | string | 'LiquidTapClient' | Arbitrary name to use in the WS url. | | authenticationTimeout | number (ms) | 5000 | Timeout to assume authentication has failed. (Note a auth_failed event is expected) | | authRetryDelay | number (ms) | 200 | Time to wait before retrying authentication. | | authRetryMaxAttempts | number | 3 | Maximum number of authentication retries. |

Authentication

To subscribe to protected channels, the client must provide a token_id and token_secret which has permission to view those channels. The library will attempt to authenticate three times by default.

Authenticate Sequence

Before Initialization

var tap = new TapClient({
  auth: { tokenId: token_id, toeknSecret: token_secret }
});
// Refer to profile page for user_id: https://app.liquid.com/settings/profile
var protected_channel = tap.subscribe("user_<user_id>");
protected_channel.bind("updated", function(data) {
  console.log("sensitive user data has been updated", data);
});

After Initialization

The library allows the LiquidTap client to be created and subscribe to public channels, then when a protected channel is required the client can authenticate.

var tap = new TapClient();

var public_channel = tap.subscribe("product_cash_btcsgd_7");
public_channel.bind("updated", function(data) {
  console.log("product_cash_btcsgd_7 has been updated", data);
});

tap.authenticate({ tokenId: token_id, tokenSecret: token_secret });
var protected_channel = tap.subscribe("user_<user_id>");
protected_channel.bind("updated", function(data) {
  console.log("sensitive user data has been updated", data);
});

Authentication Input

The authentication can be done either by providing an API token ID and secret, JWT token, or callback.

Token ID and Secret

var tap = new TapClient({
  auth: { tokenId: token_id, tokenSecret: token_secret }
});
var tap = new TapClient();
tap.authenticate({ tokenId: token_id, tokenSecret: token_secret });

Signed JWT

var tap = new TapClient({ auth: signed_jwt });
var tap = new TapClient();
tap.authenticate(signed_jwt);

Callback (return string)

var tap = new TapClient({
  auth: ({ path }) => jwt.encode({token_id: my_token_id, path: path}, my_secret)
});

Callback (return Promise)

The authentication process inside TapClient will wait for the promise to resolve before authenticating.

const createJwtWhenReady = ({ path }) => {
  return new Promise<string>(
    (resolve) => {
        setTimeout(
          () => resolve(jwt.encode({token_id: my_token_id, path: path}, my_secret)), 
          some_wait_period
        )
    })
}
var tap = new TapClient({
  auth: createJwtWhenReady
});

TapClient will also wrap the promise to allow process order management

var tap = new TapClient();
const createJwtWhenReady = ({ path }) => {
  return new Promise<string>(
    (resolve) => {
        setTimeout(
          () => resolve(jwt.encode({token_id: my_token_id, path: path}, my_secret)), 
          some_wait_period
        )
    })
}
tap.authenticate({
  auth: createJwtWhenReady
})
.then(() => {
  // do something
})
.catch(() => {
  // some error in either generating the jwt, or the websocket request event
})

Callback (which takes another callback)

var tap = new TapClient();

// Create a service to manage nonce and JWT creation
const createJwtWhenReady = ({ path }, callback) => {
    setTimeout(
      () => {
        nonce_counter += 1;
        // this callback will return a Promise that resolves when the auth request comes back, either success or failure
        await callback(jwt.encode({token_id: my_token_id, path: path, nonce: nonce_counter }, my_secret));
      }, some_wait_period
    )
}

tap.authenticate({
  auth: createJwtWhenReady
})
.then(() => {
  // will be called after the resolver for the above JWT creator
})
.catch(() => {
  // log error
})

Troubleshooting

Open the chrome dev tools and inspect the network traffic as shown in the image below: inspecting websocket frames

Contributing

Setup

npm install

Development

npm run build:dev
npm run sample

Testing

npm test

Ensure changes are also thoroughly tested with the real world server responses.

Building

npm run build

Ensure to commit compiled assets in dist.