Skip to content

Presence Fail #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.swp
*.DS_Store
node_modules
package-lock.json
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,42 @@

The JSON OT type can be used to edit arbitrary JSON documents.

It has been forked from https://github.com/ottypes/json0 and modified to add Presence.

## Presence

(inspired by https://github.com/Teamwork/ot-rich-text#presence)

The shape of our presence data is as follows:

```
{
u: '123', // user ID
c: 8, // number of changes made by this user
s: [ // list of selections
[ 1, 1 ], // collapsed selection
[ 5, 7 ], // forward selection
[ 9, 4 ] // backward selection
]
}
```

Each selection listed in `s` ends with a 2-element array containing the selection start index and the selection end index. The elements in the array preceeding the last two represent the path of a `text0` entry within the `json0` data structure.

For example, the following entry in the `s` array represents the user's cursor position within the `content` field (`data.content`):

```
['content', 2, 2]
```

We can access deeply nested entries with this structure as well. For example, the following `s` entry represents a text selection in `data.files[3].text`:

```
['files', 3, 'text', 4, 7]
```

The rest of the README content is from the original repo https://github.com/ottypes/json0.

## Features

The JSON OT type supports the following operations:
Expand Down
57 changes: 57 additions & 0 deletions lib/json0.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,63 @@ function convertToText(c) {
delete c.o;
}

// not checking anything here, we should probably check that u: exists
// (only thing we care about at json0 top level), and then delegate
// to any subtypes if there is already subtype presence data
json.createPresence = function(presence) {
return presence;
};

// this needs more thinking/testing, looking a bit more carefully at
// how this is implemented in ot-rich-text, etc.
json.comparePresence = function(pres1, pres2) {
if (!pres1 || !pres2) {
return false;
}
if (!pres1.p || !pres2.p) {
return false;
}
if (pres1.t !== pres2.t) {
return false;
}
if (pres1.t && subtypes[pres1.t]) {
if (pres1.p[0] === pres2.p[0]) {
return subtypes[pres1.t].comparePresence(pres1, pres2);
}
} else return pres1 === pres2;
};

// this is the key function, always run client-side, both on
// the client that creates a text-change, and on the clients
// that receive text-changes (ops). if there are no ops, just
// return presence, if there are ops, delegate to the subtype
// responsible for those ops (currently only ot-rich-text).
// I am making assumptions many places that all ops will be
// of the same subtype, not sure if this is a given.
// We're only concerned about the first level of object/array,
// not sure if the spec allows nesting of subtypes.
json.transformPresence = function(presence, op, isOwn) {
if (op.length < 1) {
return presence;
}
const representativeOp = op[0];
const opType = op[0].t;
const path = representativeOp.p && representativeOp.p[0]
if (opType && subtypes[opType] && path) {
if (!presence.p || !presence.p[0] || presence.p[0] !== path) {
return presence
}
// return result of running the subtype's transformPresence,
// but add path and type, which the subtype will not include
presence = {
...subtypes[opType].transformPresence(presence, op, isOwn),
p: op[0].p,
t: op[0].t
};
}
return presence;
};

json.apply = function(snapshot, op) {
json.checkValidOp(op);

Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ot-json0",
"version": "1.1.0",
"name": "@houshuang/ot-json0",
"version": "1.2.0",
"description": "JSON OT type",
"main": "lib/index.js",
"directories": {
Expand All @@ -9,15 +9,14 @@
"dependencies": {},
"devDependencies": {
"ot-fuzzer": "^1.0.0",
"mocha": "^1.20.1",
"coffee-script": "^1.7.1"
"mocha": "^1.20.1"
},
"scripts": {
"test": "mocha"
},
"repository": {
"type": "git",
"url": "git://github.com/ottypes/json0"
"url": "git://github.com/houshuang/json0"
},
"keywords": [
"ot",
Expand Down
176 changes: 0 additions & 176 deletions test/json0-generator.coffee

This file was deleted.

Loading