Skip to content

Commit 7940c8e

Browse files
committed
Merge pull request #2 from devongovett/document-subtypes
Document subtypes and deprecate old text ops
2 parents 5cfcfbe + 1e81053 commit 7940c8e

1 file changed

Lines changed: 103 additions & 43 deletions

File tree

README.md

Lines changed: 103 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ The JSON OT type can be used to edit arbitrary JSON documents.
66

77
The JSON OT type supports the following operations:
88

9-
- Embedded string editing, using the old text0 OT type
10-
- Move list items in a list, shuffling adjacent list items as needed
11-
- Object insert / object delete
9+
- Insert/delete/move/replace items in a list, shuffling adjacent list items as needed
10+
- Object insert/delete/replace
1211
- Atomic numerical add operation
12+
- Embed arbitrary subtypes
13+
- Embedded string editing, using the old text0 OT type as a subtype
1314

1415
JSON0 is an *invertable* type - which is to say, all operations have an inverse
1516
operation which will undo the original op. As such, all operations which delete
1617
content add the content to be deleted inline in the operation.
1718

1819
But its not perfect - here's a list of things it *cannot* do:
1920

20-
- Embed arbitrary subtypes
2121
- Object-move
2222
- Set if null (object insert with first writer wins semantics)
2323
- Efficient list insert-of-many-items
@@ -54,15 +54,16 @@ into the array.
5454
op | Description
5555
---------------------------------------|-------------------------------------
5656
`{p:[path], na:x}` | adds `x` to the number at `[path]`.
57-
`{p:[path,offset], si:s}` | inserts the string `s` at offset `offset` into the string at `[path]`.
58-
`{p:[path,offset], sd:s}` | deletes the string `s` at offset `offset` from the string at `[path]`.
5957
`{p:[path,idx], li:obj}` | inserts the object `obj` before the item at `idx` in the list at `[path]`.
6058
`{p:[path,idx], ld:obj}` | deletes the object `obj` from the index `idx` in the list at `[path]`.
6159
`{p:[path,idx], ld:before, li:after}` | replaces the object `before` at the index `idx` in the list at `[path]` with the object `after`.
6260
`{p:[path,idx1], lm:idx2}` | moves the object at `idx1` such that the object will be at index `idx2` in the list at `[path]`.
6361
`{p:[path,key], oi:obj}` | inserts the object `obj` into the object at `[path]` with key `key`.
6462
`{p:[path,key], od:obj}` | deletes the object `obj` with key `key` from the object at `[path]`.
6563
`{p:[path,key], od:before, oi:after}` | replaces the object `before` with the object `after` at key `key` in the object at `[path]`.
64+
`{p:[path], t:subtype, o:subtypeOp}` | applies the subtype op `o` of type `t` to the object at `[path]`
65+
`{p:[path,offset], si:s}` | inserts the string `s` at offset `offset` into the string at `[path]` (uses subtypes internally).
66+
`{p:[path,offset], sd:s}` | deletes the string `s` at offset `offset` from the string at `[path]` (uses subtypes internally).
6667

6768
---
6869

@@ -89,43 +90,6 @@ Adds X to the number at PATH. If you want to subtract, add a negative number.
8990

9091
---
9192

92-
### String operations
93-
94-
If the content at a path is a string, an operation can edit the string
95-
in-place, either deleting characters or inserting characters.
96-
97-
To edit a string, add the string offset to the path. For example, given the
98-
following object:
99-
100-
{'key':[100,'abcde']}
101-
102-
If you wanted to delete the `'d'` from the string `'abcde'`, you would use the following operation:
103-
104-
[{p:['key',1,3],sd:'d'}]
105-
106-
Note the path. The components, in order, are the key to the list, the index to
107-
the `'abcde'` string, and then the offset to the `'d'` character in the string.
108-
109-
#### Insert into a string
110-
111-
Usage:
112-
113-
{p:PATH, si:TEXT}
114-
115-
Insert `TEXT` at the location specified by `PATH`. The path must specify an
116-
offset in a string.
117-
118-
#### Delete from a string
119-
120-
Usage:
121-
122-
{p:PATH, sd:TEXT}
123-
124-
Delete `TEXT` at the location specified by `PATH`. The path must specify an
125-
offset in a string. `TEXT` must be contained at the location specified.
126-
127-
---
128-
12993
### Lists and Objects
13094

13195
Lists and objects have the same set of operations (*Insert*, *Delete*,
@@ -232,6 +196,102 @@ is equivalent to a delete followed by an insert:
232196
There is (unfortunately) no equivalent for list move with objects.
233197

234198

199+
---
200+
201+
### Subtype operations
202+
203+
Usage:
204+
205+
{p:PATH, t:SUBTYPE, o:OPERATION}
206+
207+
`PATH` is the path to the object that will be modified by the subtype.
208+
`SUBTYPE` is the name of the subtype, e.g. `"text0"`.
209+
`OPERATION` is the subtype operation itself.
210+
211+
To register a subtype, call `json0.registerSubtype` with another OT type.
212+
Specifically, a subtype is a JavaScript object with the following methods:
213+
214+
* `apply`
215+
* `transform`
216+
* `compose`
217+
* `invert`
218+
219+
See the [OT types documentation](https://github.com/ottypes/docs) for details on these methods.
220+
221+
#### Text subtype
222+
223+
The old string operations are still supported (see below) but are now implemented internally as a subtype
224+
using the `text0` type. You can either continue to use the original `si` and `sd` ops documented below,
225+
or use the `text0` type as a subtype yourself.
226+
227+
To edit a string, create a `text0` subtype op. For example, given the
228+
following object:
229+
230+
{'key':[100,'abcde']}
231+
232+
If you wanted to delete the `'d'` from the string `'abcde'`, you would use the following operation:
233+
234+
[{p:['key',1], t: 'text0', o:[{p:3, d:'d'}]}
235+
236+
Note the path. The components, in order, are the key to the list, and the index to
237+
the `'abcde'` string. The offset to the `'d'` character in the string is given in
238+
the subtype operation.
239+
240+
##### Insert into a string
241+
242+
Usage:
243+
244+
{p:PATH, t:'text0', o:[{p:OFFSET, i:TEXT}]}
245+
246+
Insert `TEXT` to the string specified by `PATH` at the position specified by `OFFSET`.
247+
248+
##### Delete from a string
249+
250+
Usage:
251+
252+
{p:PATH, t:'text0', o:[{p:OFFSET, d:TEXT}]}
253+
254+
Delete `TEXT` in the string specified by `PATH` at the position specified by `OFFSET`.
255+
256+
---
257+
258+
### String operations
259+
260+
These operations are now internally implemented as subtype operations using the `text0` type, but you can still use them if you like. See above.
261+
262+
If the content at a path is a string, an operation can edit the string
263+
in-place, either deleting characters or inserting characters.
264+
265+
To edit a string, add the string offset to the path. For example, given the
266+
following object:
267+
268+
{'key':[100,'abcde']}
269+
270+
If you wanted to delete the `'d'` from the string `'abcde'`, you would use the following operation:
271+
272+
[{p:['key',1,3],sd:'d'}]
273+
274+
Note the path. The components, in order, are the key to the list, the index to
275+
the `'abcde'` string, and then the offset to the `'d'` character in the string.
276+
277+
#### Insert into a string
278+
279+
Usage:
280+
281+
{p:PATH, si:TEXT}
282+
283+
Insert `TEXT` at the location specified by `PATH`. The path must specify an
284+
offset in a string.
285+
286+
#### Delete from a string
287+
288+
Usage:
289+
290+
{p:PATH, sd:TEXT}
291+
292+
Delete `TEXT` at the location specified by `PATH`. The path must specify an
293+
offset in a string. `TEXT` must be contained at the location specified.
294+
235295
---
236296

237297
# Commentary

0 commit comments

Comments
 (0)