From 0e7da017fe7211965a2486a069afb3678caa3d48 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Fri, 9 Aug 2019 01:15:33 +0200 Subject: [PATCH] Use lib0/any-encoding instead of JSON --- package-lock.json | 55 ++++++++++++++----- package.json | 2 +- src/index.js | 1 + src/internals.js | 1 + src/structs/ContentAny.js | 108 ++++++++++++++++++++++++++++++++++++++ src/structs/Item.js | 4 +- src/types/AbstractType.js | 8 +-- tests/encoding.tests.js | 8 +-- 8 files changed, 164 insertions(+), 23 deletions(-) create mode 100644 src/structs/ContentAny.js diff --git a/package-lock.json b/package-lock.json index 20a9d4a6..b81434e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1490,7 +1490,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1511,12 +1512,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1531,17 +1534,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1658,7 +1664,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1670,6 +1677,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1684,6 +1692,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1691,12 +1700,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1715,6 +1726,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1795,7 +1807,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1807,6 +1820,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1892,7 +1906,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -1928,6 +1943,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1947,6 +1963,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1990,12 +2007,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -2577,9 +2596,9 @@ } }, "lib0": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.0.5.tgz", - "integrity": "sha512-3ElV6/t5Lv0Eczlnh/05q+Uq3RxQ/Q0zdN6LVtaUERQIDDZsP/CUXEGLsV8KZTgZwVFNCPGXNWYE+3WTOo+SHw==" + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.0.6.tgz", + "integrity": "sha512-drb8LcwZu2rAmTsXN0d3hFtZVbPE5ZUrsWf307Boc/v7IrmLq3lM5+OOMY672EysHTWeXo/OH54wRHyD6eFXXw==" }, "linkify-it": { "version": "2.1.0", @@ -4366,6 +4385,14 @@ "dev": true, "requires": { "lib0": "0.0.5" + }, + "dependencies": { + "lib0": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.0.5.tgz", + "integrity": "sha512-3ElV6/t5Lv0Eczlnh/05q+Uq3RxQ/Q0zdN6LVtaUERQIDDZsP/CUXEGLsV8KZTgZwVFNCPGXNWYE+3WTOo+SHw==", + "dev": true + } } }, "yallist": { diff --git a/package.json b/package.json index cc0e099f..c6140240 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ }, "homepage": "http://y-js.org", "dependencies": { - "lib0": "0.0.5" + "lib0": "0.0.6" }, "devDependencies": { "concurrently": "^3.6.1", diff --git a/src/index.js b/src/index.js index 73d4e76c..b3288e06 100644 --- a/src/index.js +++ b/src/index.js @@ -21,6 +21,7 @@ export { ContentEmbed, ContentFormat, ContentJSON, + ContentAny, ContentString, ContentType, AbstractType, diff --git a/src/internals.js b/src/internals.js index 74ce0eba..d5ac7848 100644 --- a/src/internals.js +++ b/src/internals.js @@ -27,6 +27,7 @@ export * from './structs/ContentDeleted.js' export * from './structs/ContentEmbed.js' export * from './structs/ContentFormat.js' export * from './structs/ContentJSON.js' +export * from './structs/ContentAny.js' export * from './structs/ContentString.js' export * from './structs/ContentType.js' export * from './structs/Item.js' diff --git a/src/structs/ContentAny.js b/src/structs/ContentAny.js new file mode 100644 index 00000000..1367cbae --- /dev/null +++ b/src/structs/ContentAny.js @@ -0,0 +1,108 @@ +import { + Transaction, Item, StructStore // eslint-disable-line +} from '../internals.js' + +import * as encoding from 'lib0/encoding.js' +import * as decoding from 'lib0/decoding.js' + +/** + * @private + */ +export class ContentAny { + /** + * @param {Array} arr + */ + constructor (arr) { + /** + * @type {Array} + */ + this.arr = arr + } + /** + * @return {number} + */ + getLength () { + return this.arr.length + } + /** + * @return {Array} + */ + getContent () { + return this.arr + } + /** + * @return {boolean} + */ + isCountable () { + return true + } + /** + * @return {ContentAny} + */ + copy () { + return new ContentAny(this.arr) + } + /** + * @param {number} offset + * @return {ContentAny} + */ + splice (offset) { + const right = new ContentAny(this.arr.slice(offset)) + this.arr = this.arr.slice(0, offset) + return right + } + /** + * @param {ContentAny} right + * @return {boolean} + */ + mergeWith (right) { + this.arr = this.arr.concat(right.arr) + return true + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate (transaction, item) {} + /** + * @param {Transaction} transaction + */ + delete (transaction) {} + /** + * @param {StructStore} store + */ + gc (store) {} + /** + * @param {encoding.Encoder} encoder + * @param {number} offset + */ + write (encoder, offset) { + const len = this.arr.length + encoding.writeVarUint(encoder, len - offset) + for (let i = offset; i < len; i++) { + const c = this.arr[i] + encoding.writeAny(encoder, c) + } + } + /** + * @return {number} + */ + getRef () { + return 8 + } +} + +/** + * @private + * + * @param {decoding.Decoder} decoder + * @return {ContentAny} + */ +export const readContentAny = decoder => { + const len = decoding.readVarUint(decoder) + const cs = [] + for (let i = 0; i < len; i++) { + cs.push(decoding.readAny(decoder)) + } + return new ContentAny(cs) +} diff --git a/src/structs/Item.js b/src/structs/Item.js index 9d7e46fe..95530b6e 100644 --- a/src/structs/Item.js +++ b/src/structs/Item.js @@ -18,6 +18,7 @@ import { readContentDeleted, readContentBinary, readContentJSON, + readContentAny, readContentString, readContentEmbed, readContentFormat, @@ -561,7 +562,8 @@ export const contentRefs = [ readContentString, readContentEmbed, readContentFormat, - readContentType + readContentType, + readContentAny ] /** diff --git a/src/types/AbstractType.js b/src/types/AbstractType.js index dd4ae2cd..9207c175 100644 --- a/src/types/AbstractType.js +++ b/src/types/AbstractType.js @@ -7,7 +7,7 @@ import { nextID, isVisible, ContentType, - ContentJSON, + ContentAny, ContentBinary, createID, getItemCleanStart, @@ -374,7 +374,7 @@ export const typeListInsertGenericsAfter = (transaction, parent, referenceItem, let jsonContent = [] const packJsonContent = () => { if (jsonContent.length > 0) { - left = new Item(nextID(transaction), left, left === null ? null : left.lastId, right, right === null ? null : right.id, parent, null, new ContentJSON(jsonContent)) + left = new Item(nextID(transaction), left, left === null ? null : left.lastId, right, right === null ? null : right.id, parent, null, new ContentAny(jsonContent)) left.integrate(transaction) jsonContent = [] } @@ -503,7 +503,7 @@ export const typeMapSet = (transaction, parent, key, value) => { const left = parent._map.get(key) || null let content if (value == null) { - content = new ContentJSON([value]) + content = new ContentAny([value]) } else { switch (value.constructor) { case Number: @@ -511,7 +511,7 @@ export const typeMapSet = (transaction, parent, key, value) => { case Boolean: case Array: case String: - content = new ContentJSON([value]) + content = new ContentAny([value]) break case Uint8Array: content = new ContentBinary(value) diff --git a/tests/encoding.tests.js b/tests/encoding.tests.js index 387c385d..a9160ef8 100644 --- a/tests/encoding.tests.js +++ b/tests/encoding.tests.js @@ -8,19 +8,21 @@ import { readContentJSON, readContentEmbed, readContentType, - readContentFormat + readContentFormat, + readContentAny } from '../src/internals.js' /** * @param {t.TestCase} tc */ export const testStructReferences = tc => { - t.assert(contentRefs.length === 8) + t.assert(contentRefs.length === 9) t.assert(contentRefs[1] === readContentDeleted) - t.assert(contentRefs[2] === readContentJSON) + t.assert(contentRefs[2] === readContentJSON) // TODO: deprecate content json? t.assert(contentRefs[3] === readContentBinary) t.assert(contentRefs[4] === readContentString) t.assert(contentRefs[5] === readContentEmbed) t.assert(contentRefs[6] === readContentFormat) t.assert(contentRefs[7] === readContentType) + t.assert(contentRefs[8] === readContentAny) }