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

otter-js

v0.3.0

Published

Operational Transformation library for Relatime Collaborative Editing

Downloads

17

Readme

Otter

Otter is a library to support collaborative realtime editing using Operational Transformation. This repository contains the JavaScript-implementation for use both in a browser and in a Node-based server.

A Java-implementation is also available.

Using Otter

Install via NPM:

npm install --save otter-js

Otter consists of three parts, the operations library, the editing engine and a high level model. The high level model is what you usually want to use unless you are implementing something special.

Operations

The lowest level of Otter is the operational transformation algorithms. Otter supports transformations on maps, lists and strings. There is also a combined type that can be used to combine several other types based on unique identifiers. All of these transformations are used together to create the higher level model.

Engine

The engine contains editing control. It provides support for creating editors on top of any supported operational transformation.

const string = require('otter-js/operations/string');
const Editor = require('otter-js/engine/editor');

const sync = new YourOperationSync(string.newType(), ...);
const editor = new Editor(sync);

// Connect and do something with the current version
editor.connect()
	.then(() => {
		editor.current.apply(...);
		editor.on('change', function(e) {
			// This will receive all operations that occur on the editor
		});
	});


// Perform an operation
editor.apply(string.delta()
	.retain(currentStringLength)
	.insert('abc')
	.done()
);

Editors require a synchronization helper for sending and receiving operations from a server. There is intentionally no default implementation of such a sync as different applications will have different requirements here.

In the end all operations performed by an editor will end up being handled by an instance of EditorControl.

const EditorControl = require('otter-js/engine/editor-control');

const control = new EditorControl(historyStorage);

control.latest()
	.then(latestVersion => {
		// Do something with the latest version
	});


// When an operation is received from a client it needs to be stored and
// the result needs to be sent back to all clients
control.store(taggedOperation)
	.then(op => {
		// Op should be sent back to all clients
	});

Model

This is the high level API that makes it easier to work with shared editing. The model provides shared objects of different types that are synchronized between all editors of the model.

Here is a tiny example of working with the model:

const combined = require('otter-js/operations/combined');
const Editor = require('otter-js/engine/editor');
const Model = require('otter-js/model');

const sync = new YourOperationSync(combined.newType(), ...);
const editor = new Editor(sync);
const model = new Model(editor);

model.open()
	.then(function() {
		// Create a new string and store it in the root map
		const title = model.newString();
		title.set('Cookies are tasty');
		model.set('title', title);

		// Set a primitive value in the map
		model.set('priority', 10);
	});