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 🙏

© 2025 – Pkg Stats / Ryan Hefner

angelia.io

v4.0.91

Published

WebSockets Server and Client API for node.js and the browser, with rooms support.

Downloads

243

Readme

angelia.io

WebSockets Server and Client API for Node.js and the browser, with rooms support.

The goal of this project is to provide a developer friendly API that just works™.

Installation

npm install angelia.io

Example

// server.js (node.js)

import Server from 'angelia.io/server'

class FancyChat {
	typing(socket, data, callback) {
		console.log('Im', data ? ' typing' : ' not typing')
	}
	theMessage(socket, data, callback) {
		console.log('the message is', data, socket)
		socket.emit('gotIt', 'thanks')
		callback('yes Im sure')
	}
}

Server.on(FancyChat)

class myConnection {
	connect(socket, request) {
		console.log('socket connected', socket)
	}
	disconnect(socket, code, message) {
		console.log('socket disconnected', code, message, socket)
	}
}
Server.on(myConnection)

Server.listen()

// index.js (browser)

import Client from 'angelia.io/client'

const socket = new Client('ws://localhost:3001')

socket.emit('typing', true)

setTimeout(() => {
	socket.emit('typing', false)
	socket.emit('theMessage', 'hi there!', data => {
		console.log('yep', data)
	})
}, 5000)

socket.on('gotIt', message => {
	console.log('Server got it', message)
})

Server Documentation (Node.js)

Server.listen Options

| name | kind | default | description | | -------------------- | ------- | --------- | ------------------------------------------------------------------------------ | | hostname | String | undefined | the hostname if any | | port | Number | 3001 | the port to use for this server | | maxMessageSize | Number | 5 | max size in mb of a message received | | maxPostSize | Number | 50 | max size in mb of a POST message | | skipUTF8Validation | Boolean | false | allows to skip utf8 validation | | timeout | Number | 60000 | time in milliseconds after a socket is considered gone, minimum value is 10000 |

Server Object

The server object can be accessed from everywhere

List of Server Object Properties

| signature | kind | description | | ------------------------------------- | -------- | ---------------------------------------------------------------------------------------------- | | since | Number | timestamp of initialization | | now | Number | timestamp that updates every half a second | | port | Number | port used by this server | | hostname | String | the hostname if any | | maxMessageSize | Number | maximum message size in mb | | maxPostSize | Number | maximum POST size in mb | | timeout | Number | after how long the socket is considered gone, in ms | | connections | Number | count of sockets connected | | served | Number | count of sockets ever connected | | bytesReceived | Number | sum of bytes the server has ever received | | bytesSent | Number | sum of bytes sent by the server | | messagesGarbage | Number | count of messages without a listener | | messagesReceived | Number | count of messages ever received | | messagesSent | Number | count of messages ever sent | | messagesSentCacheHit | Number | count of messages ever sent that were cached | | serverErrors | Number | count of server errors | | socketErrors | Number | count of socket errors | | events | Object | ref to events, ex: server.events.typing() to dispatch typing to anyone listening to it | | on(Class) | Function | attaches all methods of a Class as listeners | | emit(key, [value]) | Function | emits to all connected sockets | | once(key, [value]) | Function | emits to the sockets and replace if exists a pending message with the same key | | broadcast(sender, key, [value]) | Function | emits to all connected sockets except sender | | broadcastOnce(sender, key, [value]) | Function | emits to the sockets except sender and replace if exists a pending message with the same key | | sockets | Set | a Set() with all the current connected sockets |

Socket Object

The socket object is given to you by a listener

List of Socket Object Properties

| signature | kind | description | | --------------------------- | -------- | ----------------------------------------------------------------------------- | | server | Object | reference to the server | | ip | String | ip of the socket | | userAgent | String | user agent of the socket | | params | Object | the params sent via the client constructor | | since | Number | timestamp of first seen | | seen | Number | timestamp of last received message | | ping | Number | delay with the socket in milliseconds (full round trip) | | timedout | Boolean | whether we lost connection with this socket | | bytesSent | Number | sum of bytes sent to this socket | | bytesReceived | Number | sum of bytes received from this socket | | messagesSent | Number | count of messages sent to this socket | | messagesReceived | Number | count of messages received from this socket | | rooms | Set | a set with the rooms where this socket is in | | emit(key, [value]) | Function | emits to client | | once(key, [value]) | Function | replace if exists a pending message with the same key from emit queue | | disconnect([noReconnect]) | Function | disconnects the socket from the server, pass true to prevent re-connections |

Server Listeners

Listen to an event by creating a class with any name, and give to methods the name of the things you want to listen to. Then add the class to the listeners as Server.on(MyClass) and you are done.

On user defined listeners, the listener receives three things as sent by the client: socket, data and a callback; Example: class FancyChat { typing(socket, data, callback?) { console.log(socket, data) }}.

List of Predefined Server Events

There's a bunch of handy predefined events dispatched

| signature | description | | ----------------------------------- | ----------------------------------------------------------------------------------------- | | listen() | when the server is about to listen | | connect(socket, request) | when a socket connects | | disconnect(socket, code, message) | when a socket gets disconnected | | ping(socket) | when we got an update of the ping for a socket | | timeout(socket, delay) | when we are about to disconnect a timedout socket, gives the delay in milliseconds | | garbage(socket, data) | if the client sends a message that the server has no listener this will be dispatched | | incoming(socket, messages) | for debugging: ref to array of incoming messages received before dispatching to listeners | | outgoing(socket, messages) | for debugging: ref to array of outgoing messages before sending to socket |

Client API (Browser)

Client Options

Arguments for the constructor

const socket = new Client({
	url: 'ws://localhost:3001',
	params: function () {
		return { fast: 'data', test: 'a space' }
	},
	noConnect: true,
})
socket.connect()

You may also do like this if you don't need any option

const socket = new Client('ws://localhost:3001')

Client API

The client API is similar to regular event handling

| signature | kind | description | | ------------------------------ | -------- | ------------------------------------------------------------------ | | connected | Boolean | true when the socket is connected else false | | connect() | Function | connects to the server, it auto-connects on disconnection | | disconnect([noReconnect]) | Function | disconnects from the server, pass true to prevent re-connections | | on(key, callback) | Function | listens for an event, returns an off function to stop listening | | emit(key, [value, callback]) | Function | emits data to the server |

List of Predefined Client Events

As in socket.on('connect', () => console.log('connect happened!'))

| signature | description | | ------------ | -------------------------------------------------------------------------------------------------------- | | connect | this happens only once when we connect to the server, any future connection is a reconnect | | reconnect | if we were connected at least once, then any re-connection will dispatch this event instead of connect | | disconnect | when we disconnect from the server |

Rooms

Via a Rooms list

  1. Create a room class that extends Room
  2. Create a room list that will allow joining sockets
  3. Join a socket in a room, a socket may join multiple rooms. Rooms are created when the id of the room doesn't exists, and deleted when there are no sockets in the room and the room doesn't have the flag persistent
  4. A socket will leave automatically all rooms on disconnection
  5. socket.rooms is a set with all the rooms the socket joined
  6. id is assigned to the room on creation
import { Room, Rooms } from 'angelia.io/server'

class GameRoom extends Room {
	persistent = false

	onCreate(socket) {
		console.log('creating room', this.id, socket)
	}
	onDelete(socket) {
		console.log('deleting room', this.id, socket)
	}

	onJoin(socket) {
		console.log('socket joined room', this.id, socket)
		socket.game = this
		this.emit('user joined', 'data here')
	}
	onLeave(socket) {
		console.log('socket left room', this.id, socket)
		socket.game = undefined
		this.emit('user left', 'data here')
	}
}

// games is a room list
const games = new Rooms(GameRoom)

class Connection {
	connect(socket) {
		games.join(socket, 'room id here')
		socket.game.id === 'room id here'
		console.log(socket.rooms)
		games.leave(socket, 'room id here')

		games.join(socket, 'a different room')
		socket.game.id === 'a different room'
		games.leave(socket, 'a different room')
	}
}

Server.on(Connection)
Server.listen()

Rooms Class

Iterating returns the rooms

| signature | kind | description | | ------------------------------------- | -------- | --------------------------------------------- | | get(id) | method | gets room with such an id | | join(socket, [id]) | method | adds socket to room id | | leave(socket, [id]) | method | removes socket from room id | | connections | number | number of sockets in this room list | | sockets | Iterator | sockets in this room list | | emit(key, [value]) | method | emits to all sockets in this room list | | once(key, [value]) | method | emits once to all sockets in this room list | | broadcast(socket, key, [value]) | method | emits to other sockets in this room list | | broadcastOnce(socket, key, [value]) | method | emits once to other sockets in this room list | | map(fn) | method | returns mapped array | | filter(fn) | method | returns mapped filtered array |

Via a Room

  1. Create a room instance that extends Room
  2. Join a socket in a room, a socket may join multiple rooms.
  3. A socket will leave automatically all rooms on disconnection
  4. socket.rooms is a set with all the rooms the socket joined
  5. Keep in mind that onCreate and onDelete are not dispatched when the room is manged by yourself. The construtor could be used for simulating onCreate and onDelete only you will know when to dispose such a variable.
import { Room } from 'angelia.io/server'

class Lobby extends Room {
	persistent = true
	id = 'lobby'
	onJoin(socket) {
		console.log('socket joined room', this.id, socket)
	}
}

// lobby is just 1 room
const lobby = new Lobby()

class Connection {
	connect(socket) {
		lobby.join(socket)

		lobby.leave(socket)
	}
}

Server.on(Connection)
Server.listen()

Room Class

Iterating returns the sockets

| signature | kind | description | | ------------------------------------- | ------- | ------------------------------------------------ | | onCreate(socket) | method | dispatched when the room is created | | onDelete(socket) | method | dispatched when the room is deleted | | onJoin(socket) | method | dispatched when a socket joins the room | | onLeave(socket) | method | dispatched when a socket leaves the room | | persistent | boolean | to not delete rooms when there are no sockets in | | connections | number | number of sockets in the room | | sockets | Set | sockets in the room | | emit(key, [value]) | method | emits to all sockets in the room | | once(key, [value]) | method | emits once to all sockets in the room | | broadcast(socket, key, [value]) | method | emits to other sockets in the room | | broadcastOnce(socket, key, [value]) | method | emits once to other sockets in the room | | id | any | the room id | | join(socket) | method | adds a socket to the room | | leave(socket) | method | remves a socket from the room |

sockets Object in Room and Rooms

Like Set but with two aditional methods

| signature | kind | description | | ------------ | ------ | ----------------------------- | | map(fn) | method | returns mapped array | | filter(fn) | method | returns mapped filtered array |

Authors

  • Tito Bouzout https://github.com/titoBouzout
  • Anthony K. https://github.com/boredofnames

URLs

  • https://github.com/titoBouzout/angelia.io
  • https://www.npmjs.com/package/angelia.io