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

@priolo/jess

v0.1.1

Published

A lightweight synchronization system for shared objects between clients and server.

Downloads

5

Readme

logo

Installation

npm install @priolo/jess

Jess (JavaScript Easy Sync System) A lightweight synchronization system for shared objects between clients and server.

Table of Contents

Core Components

ClientObjects
ServerObjects

How it Works

CLIENT

The ClientObjects class maintains local copies of objects
and manages communication with the server to synchronize them.
Typically used in the browser.

// create the `ClientObjects` object to manage synchronization on the CLIENT side
export const clientObjects = new ClientObjects()

// Set the modification function (in this case for an array). 
// You can use a default one or define a custom one.
// Applies and updates the `value` of an OBJECT with an ACTION
clientObjects.apply = ArrayApplicator.ApplyCommands

// Callback of `ClientObjects` executed when messages need to be sent to the SERVER
// You can use WebSockets or any other transport method
clientObjects.onSend = async (messages: ClientMessage[]) => { 
	// for example with websockets...
	websocket.send(JSON.stringify(messages))
}

// Declare to the SERVER that the CLIENT wants to observe updates of `myObject`
// `true` = the request is sent immediately and waits for confirmation from the SERVER
await clientObjects.init('myObject', true)

// store two commands locally
clientObjects.command('myObject', { type: TYPE_ARRAY_COMMAND.ADD, payload: "first row" })
clientObjects.command('myObject', { type: TYPE_ARRAY_COMMAND.ADD, payload: "second row" })

// send all stored commands to the SERVER to synchronize the observed OBJECTS
clientObjects.update()

// retrieve the value of an OBJECT
const myObject = clientObjects.getObject('myObject').value

// and its TEMPORARY value
const myObject = clientObjects.getObject('myObject').valueTemp

SERVER

The ServerObjects class
applies actions from CLIENTS to objects on the SERVER
and sends updates to the CLIENTS themselves.
Typically used on a Node.js server.

// create the `ServerObjects` object to manage synchronization on the SERVER side
export const serverObjects = new ServerObjects()

// Set the modification function (in this case for an array).
// You can use a default one or define a custom one.
// Applies and updates the `value` of an OBJECT with an ACTION
serverObjects.apply = ArrayApplicator.ApplyCommands

// Callback of `ServerObjects` executed when messages need to be sent to the CLIENT
// You can use WebSockets or any other transport method
// In this case, send messages to the CLIENT via WebSocket
server.onSend = async (client: any , message: ServerMessage) => 
	(<WebSocket>client).send(JSON.stringify(message))

// to be called when the chosen transport system receives a message from a CLIENT
// for example with WebSockets...
wss.on('connection', (ws: WebSocket) => {
	ws.on('message', (data: string) => server.receive(data.toString(), ws))
	// when the CLIENT disconnects, remove it from the LISTENERS
	ws.on('close', () => server.disconnect(ws))
})

// update all CLIENTS in LISTENERS
server.update()

LOCAL EXAMPLE

// create CLIENT and SERVER
const server = new ServerObjects()
const client = new ClientObjects()

// when the SERVER needs to send, write directly to the CLIENT's "receiver"
server.onSend = async (client, message) => client.receive(JSON.stringify(message))
// and vice versa
client.onSend = async (messages) => server.receive(JSON.stringify(messages), client)

/** use an "apply" on array */
server.apply = ApplyCommands
client.apply = ApplyCommands

// set the commands locally
await client.init("my-object", true)
client.command("my-object", { type: TYPE_ARRAY_COMMAND.ADD, payload: "first row" })
client.command("my-object", { type: TYPE_ARRAY_COMMAND.ADD, payload: "second row" })
client.command("my-object", { type: TYPE_ARRAY_COMMAND.ADD, payload: "third row" })
client.command("my-object", { type: TYPE_ARRAY_COMMAND.REMOVE, index: 1 })

// situation before synchronizing
console.log(client.getObject("my-object").value) 		// []
console.log(client.getObject("my-object").valueTemp) 	// ["first row", "third row"]
console.log(server.getObject("my-object").value) 		// []

// send the request to synchronize the observed OBJECTS to the SERVER
await client.update()
// 
server.update()

console.log(client.getObject("my-object").value) 		// ["first row", "third row"]
console.log(client.getObject("my-object").valueTemp) 	// ["first row", "third row"]
console.log(server.getObject("my-object").value) 		// ["first row", "third row"]

SLATE EXAMPLE

But what interests us most is making it work with SLATE for React!
That's exactly why JESS was created.
An example is inside this repository.

From the project root, run: cd examples/websocket_slate/server
npm install
npm run start
A websocket server should start on localhost:8080

Also from the project root, run: cd examples/websocket_slate/client
npm install
npm run dev
Open the browser at the address indicated by the prompt.

Duplicate the browser tab multiple times
and try to write something.
After the set delay time,
all browser tabs should update.

LIMITATIONS

This library is in ALPHA version.
It has not been tested in production
but it is intended to be used for a real system.
So it will soon be optimized and tested.