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

jsonsync

v0.2.0

Published

Transport-agnostic operation-rich peer-to-peer JSON synchronization

Downloads

6

Readme

JsonSync

Transport-agnostic operation-rich peer-to-peer JSON synchronization

Derived from the Canop paper.

var JsonSync = require('jsonsync')
// network must have network.on('connect', function(node))
// and network.on('disconnect', function(node)),
// network.nodes must be an array of Nodes,
// which have node.send(string), node.on('receive', function(string)).
var data = new JsonSync({network: network})
// Showing changes.
data.on('update', updateView)
// Performing a local change.
data.add('/comments/-', "This article was flabberghasting.")
data.remove('/comments/0')
  • Browser and Node.js
  • Client-client, client-server, peer-to-peer networks
  • Relies on JSON Patch
  • Supports atomic compound operations

Please note that this is not ready for production. The protocol, in particular, is subject to change. On the other hand, for demos and personal projects, go right away!

API

  • .add(path, value)
  • .remove(path)
  • .replace(path, value)
  • .move(fromPath, toPath)

To perform an atomic compound operation (ie, a sequence of operations that must happen in that order with no concurrent operation inserted within them):

var value = data.get(origin)
var op = data.remove(origin)             // First operation
data.replace(target, value, {after: op}) // Second operation

Cons

Currently, we do not guarantee intention preservation. Operations are not rebased to readjust indices based on concurrent operations. This precludes its use for character-by-character concurrent text editing. There is hope, however.

There is no lazy loading of huge lists. You get the whole JSON, and it has to be fully loaded on your node. If some JSON objects are too big, you can separate them into several JsonSync objects. For instance, if you have a chat app, you would have a separate object for each 10k messages, and your app could fetch the previous batch if it needs to go further in history.

Currently, you need to keep (and download) the whole history. We will make it possible in the future to also support automatic deletion of history that all nodes have in common, but if you enable that, it will preclude normal offline editing. (You will be able to do offline editing by performing a JSON diff when you reconnect, but your operations may be severely non-intention-preserving, requiring manual verification.)

Integration

┌──────────┐ action ┌───────┐
│CONTROLLER├───────→│       │ broadcast ┌─────────┐
└──────────┘        │ JSON  │←─────────→│ NETWORK │
┌──────────┐ update │ MODEL │           └─────────┘
│   VIEW   │←───────┤       │
└──────────┘        └───────┘

JSON Patch extensions used

  • mark: a list of integers providing a unique timestamp.
  • was: stores the old value of a destructive operation. It allows performing undo without having to recompute everything from the beginning.
  • string add and remove: (planned) allows string editing.
  • arithmetic: (planned) supports performing operations on numbers. For instance, {op: "arithmetic", path: "/score", value: "max(2*x^2, y)", var: {y: "/minScore"}.

Warnings: (mostly designed to ensure operational reversibility)

  1. The use of the add operation on objects is strictly meant for the addition of a brand new key. JSON operations that perform an add on an object where the key already exists perform no modification. Use replace to update the value of a key.
  2. The copy and move operations must not have path be a proper prefix of the from location; ie., a location cannot be moved nor copied to one of its ancestors. Similarly, they must not have from be a proper prefix of the path location. (For move operations, the latter is already enforced by the JSON Patch specification.) Finally, they must never overwrite a value.