{"_id":"ot-json0","_rev":"8-09256ef419689dc78083dab63f38c3f0","name":"ot-json0","description":"JSON OT type","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"ot-json0","version":"1.0.0","description":"JSON OT type","main":"lib/index.js","directories":{"test":"test"},"dependencies":{},"devDependencies":{"ot-fuzzer":"^1.0.0","mocha":"^1.20.1"},"scripts":{"test":"mocha"},"repository":{"type":"git","url":"git://github.com/ottypes/json0"},"keywords":["ot","json","sharejs","operational-transformation"],"author":{"name":"Joseph Gentle","email":"me@josephg.com"},"license":"ISC","bugs":{"url":"https://github.com/ottypes/json0/issues"},"homepage":"https://github.com/ottypes/json0","_id":"ot-json0@1.0.0","dist":{"shasum":"6b434bedcaecfa2ea3919be7c79246f368f221a6","tarball":"https://registry.npmjs.org/ot-json0/-/ot-json0-1.0.0.tgz","integrity":"sha512-RoyHgALP5Yotifj6jCf0hmOCAr4njPn1JUaEN5TlVcMkmatNSsBAJef3nSwe8pTrAaVZPCc+q+WY7zSl1iht+Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDVHJn1pFKGckVLHQPqijHuD6kCxOqSzX1uNvzrdqdiiAiAafg8aeR16QFj3j1jThVYHHo43ketLpLmIu9tpE5wJZg=="}]},"_from":".","_npmVersion":"1.4.3","_npmUser":{"name":"josephg","email":"me@josephg.com"},"maintainers":[{"name":"josephg","email":"me@josephg.com"}]},"1.0.1":{"name":"ot-json0","version":"1.0.1","description":"JSON OT type","main":"lib/index.js","directories":{"test":"test"},"dependencies":{},"devDependencies":{"ot-fuzzer":"^1.0.0","mocha":"^1.20.1","coffee-script":"^1.7.1"},"scripts":{"test":"mocha"},"repository":{"type":"git","url":"git://github.com/ottypes/json0"},"keywords":["ot","json","sharejs","operational-transformation"],"author":{"name":"Joseph Gentle","email":"me@josephg.com"},"license":"ISC","bugs":{"url":"https://github.com/ottypes/json0/issues"},"homepage":"https://github.com/ottypes/json0","_id":"ot-json0@1.0.1","dist":{"shasum":"3edfe7b73bd1f192c0737d332050e23515be354a","tarball":"https://registry.npmjs.org/ot-json0/-/ot-json0-1.0.1.tgz","integrity":"sha512-aIIAVogWmn9yjzwU2RYunKfmpLPHlgA3MeQPuGgJcT6NW/Qbn1NLLgdSHJj1i75ar8QWE1C1ZnpHCOE71sQHlw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD8U9uBFPdeQVOAWxArVzTjnLFysiY4zWwiQ8a2vmzVOwIhALOuckFYW22m+1e3JhD475jlIVAHEU//ll9rY3sFvUEt"}]},"_from":".","_npmVersion":"1.4.3","_npmUser":{"name":"josephg","email":"me@josephg.com"},"maintainers":[{"name":"josephg","email":"me@josephg.com"}]},"1.1.0":{"name":"ot-json0","version":"1.1.0","description":"JSON OT type","main":"lib/index.js","directories":{"test":"test"},"dependencies":{},"devDependencies":{"ot-fuzzer":"^1.0.0","mocha":"^1.20.1","coffee-script":"^1.7.1"},"scripts":{"test":"mocha"},"repository":{"type":"git","url":"git://github.com/ottypes/json0.git"},"keywords":["ot","json","sharejs","operational-transformation"],"author":{"name":"Joseph Gentle","email":"me@josephg.com"},"license":"ISC","bugs":{"url":"https://github.com/ottypes/json0/issues"},"homepage":"https://github.com/ottypes/json0","gitHead":"83222f417762be0e8672adb16657f0b8ba514d0d","_id":"ot-json0@1.1.0","_npmVersion":"5.5.1","_nodeVersion":"8.9.0","_npmUser":{"name":"josephg","email":"me@josephg.com"},"dist":{"integrity":"sha512-wf5fci7GGpMYRDnbbdIFQymvhsbFACMHtxjivQo5KgvAHlxekyfJ9aPsRr6YfFQthQkk4bmsl5yESrZwC/oMYQ==","shasum":"f5edeff162673b62f0f136bb64724c40ac5e590d","tarball":"https://registry.npmjs.org/ot-json0/-/ot-json0-1.1.0.tgz","fileCount":12,"unpackedSize":75858,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEE/YAeDfjJMMpvQHBRBYSFCuDxl4ms7mVuI0L7MA3cwAiB8uF9U5Z/HnFL7lO4nAW8OdhUaZvEoqsZDDSS2AwWSoQ=="}]},"maintainers":[{"name":"josephg","email":"me@josephg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ot-json0_1.1.0_1519367183432_0.460826846812572"},"_hasShrinkwrap":false}},"readme":"# JSON0 OT Type\n\nThe JSON OT type can be used to edit arbitrary JSON documents.\n\n## Features\n\nThe JSON OT type supports the following operations:\n\n- Insert/delete/move/replace items in a list, shuffling adjacent list items as needed\n- Object insert/delete/replace\n- Atomic numerical add operation\n- Embed arbitrary subtypes\n- Embedded string editing, using the old text0 OT type as a subtype\n\nJSON0 is an *invertable* type - which is to say, all operations have an inverse\noperation which will undo the original op. As such, all operations which delete\ncontent add the content to be deleted inline in the operation.\n\nBut its not perfect - here's a list of things it *cannot* do:\n\n- Object-move\n- Set if null (object insert with first writer wins semantics)\n- Efficient list insert-of-many-items\n\nIt also has O(a * b) complexity when transforming large operations by one\nanother (as opposed to O(a + b) which better algorithms can manage).\n\n\n## Operations\n\nJSON operations are lists of operation components. The operation is a grouping\nof these components, applied in order.\n\nEach operation component is an object with a `p:PATH` component. The path is a\nlist of keys to reach the target element in the document. For example, given\nthe following document:\n\n```\n{'a':[100, 200, 300], 'b': 'hi'}\n```\n\nAn operation to delete the first array element (`100`) would be the following:\n\n```\n[{p:['a', 0], ld:100}]\n```\n\nThe path (`['a', 0]`) describes how to reach the target element from the root.\nThe first element is a key in the containing object and the second is an index\ninto the array.\n\n### Summary of operations\n\n op                                    | Description\n---------------------------------------|-------------------------------------\n`{p:[path], na:x}`                     | adds `x` to the number at `[path]`.\n`{p:[path,idx], li:obj}`               | inserts the object `obj` before the item at `idx` in the list at `[path]`.\n`{p:[path,idx], ld:obj}`               | deletes the object `obj` from the index `idx` in the list at `[path]`.\n`{p:[path,idx], ld:before, li:after}`  | replaces the object `before` at the index `idx` in the list at `[path]` with the object `after`.\n`{p:[path,idx1], lm:idx2}`             | moves the object at `idx1` such that the object will be at index `idx2` in the list at `[path]`.\n`{p:[path,key], oi:obj}`               | inserts the object `obj` into the object at `[path]` with key `key`.\n`{p:[path,key], od:obj}`               | deletes the object `obj` with key `key` from the object at `[path]`.\n`{p:[path,key], od:before, oi:after}`  | replaces the object `before` with the object `after` at key `key` in the object at `[path]`.\n`{p:[path], t:subtype, o:subtypeOp}`   | applies the subtype op `o` of type `t` to the object at `[path]`\n`{p:[path,offset], si:s}`              | inserts the string `s` at offset `offset` into the string at `[path]` (uses subtypes internally).\n`{p:[path,offset], sd:s}`              | deletes the string `s` at offset `offset` from the string at `[path]` (uses subtypes internally).\n\n---\n\n### Number operations\n\nThe only operation you can perform on a number is to add to it. Remember, you\ncan always replace the number with another number by operating on the number's\ncontainer.\n\n> Are there any other ways the format should support modifying numbers? Ideas:\n>\n> - Linear multiple as well (Ie, `x = Bx + C`)\n> - MAX, MIN, etc? That would let you do timestamps...\n>\n> I can't think of any good use cases for those operations...\n\n#### Add\n\nUsage:\n\n    {p:PATH, na:X}\n\nAdds X to the number at PATH. If you want to subtract, add a negative number.\n\n---\n\n### Lists and Objects\n\nLists and objects have the same set of operations (*Insert*, *Delete*,\n*Replace*, *Move*) but their semantics are very different. List operations\nshuffle adjacent list items left or right to make space (or to remove space).\nObject operations do not. You should pick the data structure which will give\nyou the behaviour you want when you design your data model. \n\nTo make it clear what the semantics of operations will be, list operations and\nobject operations are named differently. (`li`, `ld`, `lm` for lists and `oi`,\n`od` and `om` for objects).\n\n#### Inserting, Deleting and Replacing in a list\n\nUsage:\n\n- **Insert**: `{p:PATH, li:NEWVALUE}`\n- **Delete**: `{p:PATH, ld:OLDVALUE}`\n- **Replace**: `{p:PATH, ld:OLDVALUE, li:NEWVALUE}`\n\nInserts, deletes, or replaces the element at `PATH`.\n\nThe last element in the path specifies an index in the list where elements will\nbe deleted, inserted or replaced. The index must be valid (0 <= *new index* <=\n*list length*). The indexes of existing list elements may change when new\nlist elements are added or removed.\n\nThe replace operation:\n\n    {p:PATH, ld:OLDVALUE, li:NEWVALUE}\n\nis equivalent to a delete followed by an insert:\n\n    {p:PATH, ld:OLDVALUE}\n    {p:PATH, li:NEWVALUE}\n\nGiven the following list:\n\n    [100, 300, 400]\n\napplying the following operation:\n\n    [{p:[1], li:{'yo':'hi there'}}, {p:[3], ld:400}]\n\nwould result in the following new list:\n\n    [100, {'yo':'hi there'}, 300]\n\n\n#### Moving list elements\n\nYou can move list items by deleting them and & inserting them back elsewhere,\nbut if you do that concurrent operations on the deleted element will be lost.\nTo fix this, the JSON OT type has a special list move operation.\n\nUsage:\n\n    {p:PATH, lm:NEWINDEX}\n\nMoves the list element specified by `PATH` to a different place in the list,\nwith index `NEWINDEX`. Any elements between the old index and the new index\nwill get new indicies, as appropriate.\n\nThe new index must be 0 <= _index_ < _list length_. The new index will be\ninterpreted __after__ the element has been removed from its current position.\nGiven the following data:\n\n    ['a', 'b', 'c']\n\nthe following operation:\n\n    [{p:[1], lm:2}]\n\nwill result in the following data:\n\n    ['a', 'c', 'b']\n\n\n#### Inserting, Deleting and Replacing in an object\n\nUsage:\n\n- **Insert**: `{p:PATH, oi:NEWVALUE}`\n- **Delete**: `{p:PATH, od:OLDVALUE}`\n- **Replace**: `{p:PATH, od:OLDVALUE, oi:NEWVALUE}`\n\nSet the element indicated by `PATH` from `OLDVALUE` to `NEWVALUE`. The last\nelement of the path must be the key of the element to be inserted, deleted or\nreplaced.\n\nWhen inserting, the key must not already be used. When deleting or replacing a\nvalue, `OLDVALUE` must be equal to the current value the object has at the\nspecified key.\n\nAs with lists, the replace operation:\n\n    {p:PATH, od:OLDVALUE, oi:NEWVALUE}\n\nis equivalent to a delete followed by an insert:\n\n    {p:PATH, od:OLDVALUE}\n    {p:PATH, oi:NEWVALUE}\n\nThere is (unfortunately) no equivalent for list move with objects.\n\n\n---\n\n### Subtype operations\n\nUsage:\n  \n    {p:PATH, t:SUBTYPE, o:OPERATION}\n    \n`PATH` is the path to the object that will be modified by the subtype.\n`SUBTYPE` is the name of the subtype, e.g. `\"text0\"`.\n`OPERATION` is the subtype operation itself.\n\nTo register a subtype, call `json0.registerSubtype` with another OT type.\nSpecifically, a subtype is a JavaScript object with the following methods:\n\n* `apply`\n* `transform`\n* `compose`\n* `invert`\n\nSee the [OT types documentation](https://github.com/ottypes/docs) for details on these methods.\n\n#### Text subtype\n\nThe old string operations are still supported (see below) but are now implemented internally as a subtype\nusing the `text0` type. You can either continue to use the original `si` and `sd` ops documented below,\nor use the `text0` type as a subtype yourself.\n\nTo edit a string, create a `text0` subtype op. For example, given the\nfollowing object:\n\n    {'key':[100,'abcde']}\n\nIf you wanted to delete the `'d'` from the string `'abcde'`, you would use the following operation:\n\n    [{p:['key',1], t: 'text0', o:[{p:3, d:'d'}]}\n\nNote the path. The components, in order, are the key to the list, and the index to\nthe `'abcde'` string. The offset to the `'d'` character in the string is given in\nthe subtype operation.\n\n##### Insert into a string\n\nUsage:\n\n    {p:PATH, t:'text0', o:[{p:OFFSET, i:TEXT}]}\n    \nInsert `TEXT` to the string specified by `PATH` at the position specified by `OFFSET`.\n\n##### Delete from a string\n\nUsage:\n\n    {p:PATH, t:'text0', o:[{p:OFFSET, d:TEXT}]}\n    \nDelete `TEXT` in the string specified by `PATH` at the position specified by `OFFSET`.\n\n---\n\n### String operations\n\nThese operations are now internally implemented as subtype operations using the `text0` type, but you can still use them if you like. See above.\n\nIf the content at a path is a string, an operation can edit the string\nin-place, either deleting characters or inserting characters.\n\nTo edit a string, add the string offset to the path. For example, given the\nfollowing object:\n\n    {'key':[100,'abcde']}\n\nIf you wanted to delete the `'d'` from the string `'abcde'`, you would use the following operation:\n\n    [{p:['key',1,3],sd:'d'}]\n\nNote the path. The components, in order, are the key to the list, the index to\nthe `'abcde'` string, and then the offset to the `'d'` character in the string.\n\n#### Insert into a string\n\nUsage:\n\n    {p:PATH, si:TEXT}\n\nInsert `TEXT` at the location specified by `PATH`. The path must specify an\noffset in a string.\n\n#### Delete from a string\n\nUsage:\n\n    {p:PATH, sd:TEXT}\n\nDelete `TEXT` at the location specified by `PATH`. The path must specify an\noffset in a string. `TEXT` must be contained at the location specified.\n\n---\n\n# Commentary\n\nThis library was written a couple of years ago by [Jeremy Apthorp](https://github.com/nornagon). It was\noriginally written in coffeescript as part of ShareJS, and then it got pulled\nout into the share/ottypes library and its finally landed here.\n\nThe type uses the list-of-op-components model, where each operation makes a\nseries of individual changes to a document. Joseph now thinks this is a\nterrible idea because it doesn't scale well to large operations - it has\n(N<sup>2</sup> instead of 2N complexity).\n\nJeremy and Joseph have talked about rewriting this library to instead make each\noperation be a sparse traversal of the document. But it was obnoxiously\ndifficult to implement JSON OT correctly in the first place - it'll probably\ntake both of us thinking about nothing else for a few weeks to make that\nhappen.\n\nWhen it was written, the embedded text0 type was sharejs's text type. Its since\nbeen rewritten to make each operation be a traversal, but the JSON OT type\nstill embeds the old type. As such, that old text type is included in this\nrepository. If you want to use text0 in your own project, I'd be very happy to\npull it out of here and make it its own module. However, I recommend that you\njust use the new text type. Its simpler and faster.\n\n---\n\n# License\n\nAll code contributed to this repository is licensed under the standard MIT license:\n\nCopyright 2011 ottypes library contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following condition:\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n\n","maintainers":[{"name":"josephg","email":"me@josephg.com"}],"time":{"modified":"2022-06-23T03:58:03.543Z","created":"2014-07-17T19:05:39.888Z","1.0.0":"2014-07-17T19:05:39.888Z","1.0.1":"2015-01-07T05:48:37.112Z","1.1.0":"2018-02-23T06:26:23.611Z"},"homepage":"https://github.com/ottypes/json0","keywords":["ot","json","sharejs","operational-transformation"],"repository":{"type":"git","url":"git://github.com/ottypes/json0.git"},"author":{"name":"Joseph Gentle","email":"me@josephg.com"},"bugs":{"url":"https://github.com/ottypes/json0/issues"},"license":"ISC","readmeFilename":"README.md"}