• Stars
    star
    654
  • Rank 68,870 (Top 2 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 3 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A CRDT for asynchronous rich-text collaboration, where authors can work independently and then merge their changes.

Peritext

This is a prototype implementation of Peritext, a CRDT for rich text with inline formatting. The algorithm is described in the following publications:

This repo includes:

  • A Typescript implementation of the core Peritext CRDT algorithm
  • A prototype integration with the Prosemirror editor library
  • An interactive demo UI where you can try out the editor
  • A test suite

Try the editor demo

To see a basic interactive demo where you can type rich text into two editors and periodically sync them:

npm install

npm run start

Code tour

Algorithm code: The main algorithm implementation is in src/peritext.ts. Because the goal of this work is to eventually implement a rich text type in Automerge, we implemented Peritext as an extension to a codebase called Micromerge, which is a simplified implementation of Automerge that has mostly the same behavior but is less performance-optimized.

The essay describes the algorithm in three main parts:

  • Generating operations: happens in changeMark
  • Applying operations: happens in applyAddRemoveMark
  • Producing a document: there are two places this logic is defined. getTextWithFormatting is a "batch" approach which iterates over the internal document metadata and produces a Prosemirror document. There is also a codepath that produces incremental patches representing changes (which is actually what powers the editor demo); these patches get emitted directly while applying the op, within applyAddRemoveMark.

Prosemirror integration: src/bridge.ts contains the code for the integration between the CRDT and the Prosemirror library. There are two main pieces to the integration:

  • Prosemirror to CRDT: when a change happens in the editor, Prosemirror emits a Transaction. We turn that transaction into a list of InputOperation commands for the CRDT, inside the applyProsemirrorTransactionToMicromergeDoc function.
  • CRDT to Prosemirror: when a change happens in the Micromerge CRDT, the CRDT emits a Patch object representing what changed. We turn this into a Prosemirror transaction with the extendProsemirrorTransactionWithMicromergePatch function.

Each direction of this transformation is straightforward, because the external interface of InputOperations and Patches provided by the CRDT closesly matches the Prosemirror Transaction format.

Tests

npm run test will run the manual tests defined in test/micromerge.ts. These tests correspond to many of the specific examples explained in the essay.

You can also run a generative fuzz tester using npm run fuzz. This will randomly generate edit traces and check for convergence.

Build demo artifact for essay

This repo also contains a UI that plays back a preset trace of edit actions, which is included in the Ink & Switch essay about Peritext.

To see that UI, you can run npm run start-essay-demo.

To build an artifact for including in the essay, run npx parcel build src/essay-demo.ts, and then copy the resulting ./dist/essay-demo.js file to content/peritext/static/peritext-demo.js in the essays repo. Also copy over any CSS changes from static/essay-demo.css to content/peritext/static/peritext-styles.css if needed.

More Repositories

1

cambria-project

Schema evolution with bi-directional lenses.
TypeScript
616
star
2

farm

๐ŸŒฑ Grow delightful software
Elm
249
star
3

tiny-essay-editor

simple markdown editor w inline comments, on latest automerge stack
TypeScript
214
star
4

livebook

IPython notebook-compatible live coding experiment
Python
200
star
5

capstone

An experimental, tablet-based tool for developing your ideas
TypeScript
175
star
6

potluck

TypeScript
74
star
7

ksp-browser

Connect the things you already know in your browser.
TypeScript
71
star
8

backchannel

Local-first address book
TypeScript
67
star
9

ksp

Reference implementation of Knowledge Server Protocol (KSP)
Rust
48
star
10

backchat

A relationship-based digital identity system.
TypeScript
31
star
11

vscode-hypermerge

A VSCode plugin to edit Hypermerge documents
TypeScript
28
star
12

upwelling-code

The Upwelling research prototype.
TypeScript
23
star
13

interactive-shape-recognition

Implementaion of "A Simple Approach to Recognise Geometric Shapes Interactively" by Joaquim A. Jorge and Manuel J. Fonseca.
JavaScript
18
star
14

eup-experiment-pipes

JavaScript
16
star
15

flutter-hello

A sample flutter drawing app
Objective-C
16
star
16

cambria-automerge

TypeScript
16
star
17

here

resilient location sharing
TypeScript
12
star
18

inkling

archived prototype for sketching dynamic models
TypeScript
8
star
19

automerge-todomvc-http

An automerge TodoMVC interop demo
Rust
5
star
20

cambria-express

use cambria to migrate API requests as express middleware
TypeScript
5
star
21

farm-peer

A cloud peer for farm to keep data warm while your computer is sleeping.
TypeScript
4
star
22

discovery-cloud-client

TypeScript
4
star
23

Inkteractions

JavaScript
1
star