HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
ottypes
json1
JavaScript2019–2022
ottypes / json1

json1

This is an operational transform type replacement for ottypes/json0

4Distinct people
7Mentions
0Explicit recommenders
335GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

This is an operational transform type replacement for ottypes/json0

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year7 dated mentions

Observed mentions: 2019-05-07 11:40:14 UTC to 2022-02-17 13:35:19 UTC.

01232019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2022

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC101
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC202
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC303
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101

What Hacker News says

7 sources
The article discusses the shortcoming of CRDTs - sometimes you do want a conflict that a human can resolve, instead of an algorithms best guess: > This conflict can be surfaced to Alice, and Bob can be allowed to go about his business. Could this particular problem be resolved in a purely automatic way with a CRDT? Definitely, but it probably will not result in what you want. Last first will work of course, but then which is more right might need human review, and even worse it might result in both results being interleaved (a likely outcome!). The article goes on to suggest that with a system of sharing patches, we can synchronize our distributed data stores with more precise semantics, even if we do need human intervention on conflicts sometimes. Part of this is agreeing on patch order: > We can stack either patch in any order without d
Read the rest
ifficulty. Perhaps we ask Bob and Alice to agree on the application order (using pull / push as is done with git). But maybe we just allow them to apply when they arrive. The answer depends on the workflow. Do you know what a system that works like pull->rebase->push sounds like to me? If you squint a little? This sounds like operational transforms [1]. Especially if you are considering multiple different patching semantics - > Which of these you want, however, requires semantic direction of the diff algorithm. While lots of structured diff problems will be solved by the simplest algorithm, ultimately we need to have a schema that helps to direct the meaning of our diffs. String fields might be best line-based, word-based, or perhaps they must always be atomic (as with identifiers). Each patching semantic is a different type of Operation. Rebasing your local changes before sending your pending patches is the Transform. The main advantage of OT systems over CRDTs is that OT also allows for conflicts & human in the loop conflict resolution. @josephg built a JSON Operational Transform library [2] that has interesting operations like Move (something diff/patch really struggles with) as well as conflict resolution. The thing I like about the OT model is that it’s pretty easy to nest other approaches inside OT. Want to express 5 different patch semantics? Make an operation type for each. Want to support CRDT as well? Sure, make an operation type called CRDTUpdate that contains whatever delta data the underlying CRDT system would send. No matter what strategy you pick, remember to fuzz test your distributed sync system for convergence. [1]: https://en.m.wikipedia.org/wiki/Operational_transformation [2]: https://github.com/ottypes/json1
In What's the Difference: JSON diff and patch
> Even if we get the OT part right, it’d be huge effort to port this to support other semantic structures with different set of ops Its very doable, and its been done. Eg, in json1[1] we have support for lots of tree operations on a set of data stored as a JSON tree: - Insert / delete in lists - Move (reparent) any object in the tree - Embedded edits (so if you have a custom type inside a field and define your own operations) This is all very general purpose. You don't need to do reinvent any of this per application. [1] https://github.com/ottypes/json1
In Version Control for Structure Editing
I’m not sure how much the field has improved - good chance there’s some new papers I haven’t read. But I think it’s pretty doable. For all the talk of concurrent editing, the reality is that having multiple users edit the same value at the same time in most applications is incredibly rare. It’s rare enough that concurrent editing is just basically broken in most web apps and nobody seems to mind or talk about it. For structured / database data, the best effort merges of current systems (or doing simple last writer wins stuff) is a fine solution in 95% of applications. But ideally we want something like the semantics of ot-json-1 [1] which supports arbitrary move operations. This is necessary if you wanted to implement a program like workflowy on top of a crdt. Martin thinks this is possible in a crdt by sort of embedding part of an OT sys
Read the rest
tem and doing transform, but I don’t feel very satisfied with that answer either. The other thing I would love to see solved is how you would add git style conflicts into a crdt. The best effort merging strategy of most OT & CRDT systems is fine for real-time editing but it isn’t what you want when merging distant branches. Automerge today supports arbitrary json data, inserts, deletes and local moves. I think that’s plenty for the data model in 99% of software. I think most software that fits well into a classical database model should be reasonably straightforward to adapt. I’m not sure if that answers your question but yeah, I’m thinking about this stuff too. [1] https://github.com/ottypes/json1
In Faster CRDTs: An Adventure in Optimization
No; I wouldn't do it if I was just calling them once each in a particular order. And I don't often use this trick for simple functions. But sometimes long functions have repeated behaviour. For example, in this case I needed to do two recursive tree walks inside this function, so each walk was expressed as an inner function which recursively called itself, and each is called once from the top level method: https://github.com/ottypes/json1/blob/05ef789cc697888802e786... I don't do it like this often though. The code in this file is easily the most complex code I've written in nearly 3 decades of programming. Here my ability to read and edit the code is easily the most important factor. I think this form makes the core algorithm more clear than any other way I could factor this code. I considered smearing this internal logic out over severa
Read the rest
l top level methods, but I doubt that would be any easier to read.
In It's probably time to stop recommending Clean Code (2020)
Author of the linked blog post here. The example cases for additional types / custom implementation are in this section: https://ckeditor.com/blog/Lessons-learned-from-creating-a-ri... These content-preservation edge cases weren't possible to solve with what was available (at least at the time we started the project). Even apart of that, ottypes/json0 was lacking some basic things, like moving objects. I see they came up with a new implementation recently (https://github.com/ottypes/json1) and it allows moving objects. Maybe the new implementation would solve some problems. However, it is in "preview" state, and the last update was 2 months ago, so I am not sure how well it will be maintained. Also, there are some edge cases when transforming ranges (which CKE5 use to represent, for example, comments on text or content created in track ch
Read the rest
anges mode). I don't want to bury you in difficult to understand examples but if you are interested you might want to check the examples listed in inline codes for this function: https://github.com/ckeditor/ckeditor5-engine/blob/master/src.... As far as Quill.js is concerned, it is based on the linear data model, which brings limitations when it comes to complex features. Transformation algorithms for linear data models are much simpler and there are more implementations and articles in this area. Everything depends on your needs. If Quill.js features set and functionality fit your needs then the solution you chose is correct. With CKE5 however, we didn't want to go on any compromises. We needed complex structures for our features, and for having a powerful framework - to enable other developers to write whatever feature they want and have those features working in real-time collaboration. We wanted transformation algorithms which will handle all the edge cases. It is true, some of those cases are quite rare. And the old "10/90" mantra applies here, in this case "10% of use cases brings 90% of complexity". But those edge cases happen and we didn't want to disappoint our users.
In Open source collaborative text editors

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.