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

client-socket

v1.0.3

Published

helper module for socket clients

Downloads

3

Readme

socket-client

socket-client is a new type of client library for socket (chat) clients.

The goal: new chat clients can now be implemented using only this library, without having to mess around with socket-core itself.

Things which this library makes possible:

  • consolidates logic common to all chat clients
  • leaving and joining of channels
  • virtual messages (such as status messages) and virtual channels (currently only the !status channel)
  • handling multiple socket instances
  • receiving unread notifications and mentions for channels
  • resolving of DNS shortnames (socket.chat) to socket keys

Usage

See socket-cli for an example client implementation.

var Client = require('socket-client')

const client = new Client({
  maxFeeds: maxFeeds,
  config: {
    dbdir: archivesdir,
    temp: args.temp
  },
  // persistent caching means that we cache resolved DNS shortnames, allowing access to their sockets while offline
  persistentCache: {
    // localCache is something you have to implement yourself
    read: async function (name, err) {
      if (name in localCache) {
        var cache = localCache[name]
        if (cache.expiresAt < Date.now()) { // if ttl has expired: warn, but keep using
          console.error(`The TTL for ${name} has expired`)
        }
        return cache.key
      }
      // dns record wasn't found online and wasn't in the cache
      return null
    },
    write: async function (name, key, ttl) {
      var expireOffset = +(new Date(ttl * 1000)) // convert to epoch time
      var expiredTime = Date.now() + expireOffset
      if (!localCache) localCache = {}
      localCache[name] = { key: key, expiresAt: expiredTime }
    }
  }
})

client.createSocket()
  .then((socket) => {
    // resolves when the socket is ready, returns a SocketDetails instance
  })

API

var Client = require('socket-client')

client.js methods

var client = new Client(opts)

Create a client instance from which to manage multiple socket-core instances.

opts
    {
        // if `temp` is true no data is persisted to disk. 
        // `dbdir` is the directory to store the socket data
        config: {temp, dbdir}, 
        maxFeeds, // max amount of feeds to sync. default is 1000

        // opts.persistentCache has a read and write function. optional
        //   read: async function ()   // aka cache lookup function
        //   write: async function ()  // aka cache write function
        persistentCache 
    }

Note: If a method is written with a capitalized Client e.g. Client.scrubKey(key) it is a static method.

Client.getDatabaseVersion()

Get the current database version.

Client.scrubKey(key)

Returns a 64 bit hash if passed in e.g. socket://1337..7331 -> 1337..7331.

Client.getSocketDirectory()

Returns a string path of where all of the sockets are stored on the hard drive.

client.resolveName (name, cb)

Resolve the DNS shortname name. If name is already a socket key, it will be returned and the DNS lookup is aborted.

Returns the socket key in cb. If cb is null a Promise is returned.

client.createSocket ()

Create a new socket. Returns a promise that resolves into a SocketDetails instance.

client.addSocket (key, cb)

Add/load the socket at key. Returns a promise that resolves into a SocketDetails instance. cb is called when the socket has been initialized.

client.focusSocket (key)

Focus the socket at key, used when you want to switch from one open socket to another.

client.removeSocket (key)

Remove the socket key. Destroys everything related to it (the data is however still persisted to disk, fret not!).

client.getMessages (opts, cb, socket = this.currentSocket)

Returns a list of messages according to opts. If cb is null, a Promise is returned.

opts
    opts.olderThan // timestamp in epoch time. we want to get messages that are *older* than this ts
    opts.newerThan // timestamp in epoch time. we want to get messages that are *newer* than this ts
    opts.amount // amount of messages to get
    opts.channel // channel to get messages from. defaults to currently focused channel

client.getSocketKeys ()

Returns a list of socket keys, one for each open socket.

client.getCurrentSocket ()

Get the current socket. Returns a SocketDetails instance.

client._getSocketByKey (key)

Returns the socket-core instance corresponding to the socket key key. key is scrubbed internally.

client.socketToDetails (socket = this.currentSocket)

Returns a SocketDetails instance for the passed in socket-core instance.

client.addStatusMessage (message, channel, socket = this.currentSocket)

Add a status message, displayed client-side only, to the specified channel and socket. If no socket is specified, the currently focused socket is used.

client.getNumberUnreadMessages (channel, socket = this.currentSocket)

Returns the number of unread messages for channel.

client.getNumberMentions (channel, socket = this.currentSocket)

Returns the number of mentions in channel.

client.getMentions (channel, socket = this.currentSocket)

Returns a list of messages that triggered a mention in channel.

client.focusChannel (channel, keepUnread = false, socket = this.currentSocket)

Focus a channel. This clears the read state unless keepUnread is set to true. Emits an update.

client.unfocusChannel (channel, newChannel, Socket = this.currentSocket)

Unfocus a channel, effectively closing it. If newChannel is specified, it will be opened instead. Usually, what you do is you just use focusChannel, as that handles closing of the previously open channel for you.

client.clearStatusMessages (channel, socket = this.currentSocket)

Clear status messages for the specified channel.

client.getUsers (socket = this.currentSocket)

Returns a list of all the users for the specified socket. If no socket is specified, the currently focused socket is used.

client.getChannels (socket = this.currentSocket)

Returns a list of all channels for the specified socket. If no socket is specified, the currently focused socket is used.

client.getJoinedChannels (socket = this.currentSocket)

Returns a list of channels the user has joined for the specified socket. If no socket is specified, the currently focused socket is used.

client.getCurrentChannel ()

Returns the currently focused channel name.

client.subscribe (listener, socket = this.currentSocket)

Add a new listener for the update event.

client.unsubscribe (listener, socket = this.currentSocket)

Remove a previously added listener.

client.markChannelRead (channel, socket = this.currentSocket)

Mark the channel as read.


SocketDetails methods

Any method that returns an instance of SocketDetails will have the following methods.

publishMessage(msg, opts, cb)

Publish a message. See socket-core for the full list of options.

publishNick(nick, cb)

Announce a new nickname.

publishChannelTopic(channel=this.chname, topic, cb)

Publish a new channel topic to channel. cb is called when publishing has finished.

getTopic(channel=this.chname)

Returns the current topic of channel as a string.

getChannelMembers(channel=this.chname)

Return the list of user that have joined channel. Note: this can be a subset of all of the users in a socket.

focusChannel(channel=this.chname, keepUnread=false)

View channel, closing the previously focused channel.

unfocusChannel(channel=this.chname, newChannel)

Close channel.

addStatusMessage(message, channel=this.chname)

Add a status message, visible locally only.

getChannels()

Returns a list of all the channels in this socket.

getCurrentChannel()

Get the name of the current channel

clearVirtualMessages(channel=this.chname)

Remove all of the virtual (i.e. status) messages associated with this channel. Virtual messages are local only.

getJoinedChannels()

Returns a list of all of the channel names the user has joined.

getLocalUser()

Get your user for this socket. Returns an object containing:

{
    local: true,
    online: true,
    name: '',
    key: ''
}

getLocalName()

Get the user's name in this socket.

joinChannel(channel)

Join a channel. This is distinct from focusing a channel, as this actually tracks changes and publishes a message announcing that you have joined the channel

leaveChannel(channel)

Leave a joined channel. This publishes a message announcing that you have left the channel.

getUsers()

Returns an JSON object of all of the users in this socket. Each key is the public key of its corresponding user.

details.on('update', cb)

The event emitted when anything has changed with this instance of SocketDetails. You will typically want to rerender when it has been emitted.

_destroy ()

Destroy all of the listeners associated with this details instance

Install

With npm installed, run

$ npm install client-socket

License

AGPL-3.0-or-later