From 2053f7987a4a48ea4fff70f53d7059cd10493a8d Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Tue, 6 Jan 2026 20:35:18 +0100 Subject: [PATCH] fix all type issues --- README.md | 12 +- package-lock.json | 65 ++++++- package.json | 1 + src/utils/UndoManager.js | 18 +- src/utils/YEvent.js | 5 +- tests/IdMap.tests.js | 2 +- tests/compatibility.tests.js | 6 +- tests/doc.tests.js | 61 +++--- tests/encoding.tests.js | 10 +- tests/relativePositions.tests.js | 56 +++--- tests/snapshot.tests.js | 79 ++++---- tests/testHelper.js | 8 +- tests/undo-redo.tests.js | 313 +++++++++++++++---------------- tests/y-text.tests.js | 3 +- 14 files changed, 344 insertions(+), 295 deletions(-) diff --git a/README.md b/README.md index e2f50e74..391c811c 100644 --- a/README.md +++ b/README.md @@ -231,11 +231,13 @@ document private.
@liveblocks/yjs 🌟
-Liveblocks Yjs provides a fully -hosted WebSocket infrastructure and persisted data store for Yjs -documents. No configuration or maintenance is required. It also features -Yjs webhook events, REST API to read and update Yjs documents, and a -browser DevTools extension. + +Liveblocks Yjs + +provides a fully hosted WebSocket infrastructure and persisted data +store for Yjs documents. No configuration or maintenance is required. It +also features Yjs webhook events, REST API to read and update Yjs +documents, and a browser DevTools extension.
Hocuspocus
diff --git a/package-lock.json b/package-lock.json index b8f1bf46..4cb2b9aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "devDependencies": { "@types/node": "^22.14.1", "@y/protocols": "^1.0.6-1", + "markdownlint": "^0.40.0", "markdownlint-cli": "^0.45.0", "rollup": "^4.52.5", "standard": "^17.1.2", @@ -30,7 +31,7 @@ } }, "../lib0": { - "version": "0.2.116", + "version": "0.2.117", "license": "MIT", "bin": { "0ecdsa-generate-keypair": "src/bin/0ecdsa-generate-keypair.js", @@ -2352,6 +2353,19 @@ "node": ">= 0.4" } }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -3450,9 +3464,9 @@ } }, "node_modules/markdownlint": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", - "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.40.0.tgz", + "integrity": "sha512-UKybllYNheWac61Ia7T6fzuQNDZimFIpCg2w6hHjgV1Qu0w1TV0LlSgryUGzM0bkKQCBhy2FDhEELB73Kb0kAg==", "dev": true, "license": "MIT", "dependencies": { @@ -3463,7 +3477,8 @@ "micromark-extension-gfm-footnote": "2.1.0", "micromark-extension-gfm-table": "2.1.1", "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2" + "micromark-util-types": "2.0.2", + "string-width": "8.1.0" }, "engines": { "node": ">=20" @@ -3498,6 +3513,46 @@ "node": ">=20" } }, + "node_modules/markdownlint-cli/node_modules/markdownlint": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", + "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark": "4.0.2", + "micromark-core-commonmark": "2.0.3", + "micromark-extension-directive": "4.0.0", + "micromark-extension-gfm-autolink-literal": "2.1.0", + "micromark-extension-gfm-footnote": "2.1.0", + "micromark-extension-gfm-table": "2.1.1", + "micromark-extension-math": "3.1.0", + "micromark-util-types": "2.0.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", diff --git a/package.json b/package.json index 4b5bbcf6..a39ef823 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "devDependencies": { "@types/node": "^22.14.1", "@y/protocols": "^1.0.6-1", + "markdownlint": "^0.40.0", "markdownlint-cli": "^0.45.0", "rollup": "^4.52.5", "standard": "^17.1.2", diff --git a/src/utils/UndoManager.js b/src/utils/UndoManager.js index 41ce2427..6f243ba0 100644 --- a/src/utils/UndoManager.js +++ b/src/utils/UndoManager.js @@ -37,7 +37,7 @@ export class StackItem { */ const clearUndoManagerStackItem = (tr, um, stackItem) => { iterateStructsByIdSet(tr, stackItem.deletions, item => { - if (item instanceof Item && um.scope.some(type => type === tr.doc || isParentOf(/** @type {import('../utils/types.js').YType} */ (type), item))) { + if (item instanceof Item && um.scope.some(type => type === tr.doc || isParentOf(/** @type {YType} */ (type), item))) { keepItem(item, false) } }) @@ -79,7 +79,7 @@ const popStackItem = (undoManager, stack, eventType) => { } struct = item } - if (!struct.deleted && scope.some(type => type === transaction.doc || isParentOf(/** @type {import('../utils/types.js').YType} */ (type), /** @type {Item} */ (struct)))) { + if (!struct.deleted && scope.some(type => type === transaction.doc || isParentOf(/** @type {YType} */ (type), /** @type {Item} */ (struct)))) { itemsToDelete.push(struct) } } @@ -87,7 +87,7 @@ const popStackItem = (undoManager, stack, eventType) => { iterateStructsByIdSet(transaction, stackItem.deletions, struct => { if ( struct instanceof Item && - scope.some(type => type === transaction.doc || isParentOf(/** @type {import('../utils/types.js').YType} */ (type), struct)) && + scope.some(type => type === transaction.doc || isParentOf(/** @type {YType} */ (type), struct)) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. !stackItem.insertions.hasId(struct.id) ) { @@ -143,7 +143,7 @@ const popStackItem = (undoManager, stack, eventType) => { * @property {StackItem} StackItemEvent.stackItem * @property {any} StackItemEvent.origin * @property {'undo'|'redo'} StackItemEvent.type - * @property {Map>>} StackItemEvent.changedParentTypes + * @property {Map>>} StackItemEvent.changedParentTypes */ /** @@ -157,7 +157,7 @@ const popStackItem = (undoManager, stack, eventType) => { */ export class UndoManager extends ObservableV2 { /** - * @param {Doc|import('../utils/types.js').YType|Array} typeScope Limits the scope of the UndoManager. If this is set to a ydoc instance, all changes on that ydoc will be undone. If set to a specific type, only changes on that type or its children will be undone. Also accepts an array of types. + * @param {Doc|YType|Array} typeScope Limits the scope of the UndoManager. If this is set to a ydoc instance, all changes on that ydoc will be undone. If set to a specific type, only changes on that type or its children will be undone. Also accepts an array of types. * @param {UndoManagerOptions} options */ constructor (typeScope, { @@ -170,7 +170,7 @@ export class UndoManager extends ObservableV2 { } = {}) { super() /** - * @type {Array} + * @type {Array} */ this.scope = [] this.doc = doc @@ -210,7 +210,7 @@ export class UndoManager extends ObservableV2 { // Only track certain transactions if ( !this.captureTransaction(transaction) || - !this.scope.some(type => transaction.changedParentTypes.has(/** @type {import('../utils/types.js').YType} */ (type)) || type === this.doc) || + !this.scope.some(type => transaction.changedParentTypes.has(/** @type {YType} */ (type)) || type === this.doc) || (!this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) ) { return @@ -242,7 +242,7 @@ export class UndoManager extends ObservableV2 { } // make sure that deleted structs are not gc'd iterateStructsByIdSet(transaction, transaction.deleteSet, /** @param {Item|GC} item */ item => { - if (item instanceof Item && this.scope.some(type => type === transaction.doc || isParentOf(/** @type {import('../utils/types.js').YType} */ (type), item))) { + if (item instanceof Item && this.scope.some(type => type === transaction.doc || isParentOf(/** @type {YType} */ (type), item))) { keepItem(item, true) } }) @@ -265,7 +265,7 @@ export class UndoManager extends ObservableV2 { /** * Extend the scope. * - * @param {Array | import('../utils/types.js').YType | Doc} ytypes + * @param {Array | YType | Doc} ytypes */ addToScope (ytypes) { const tmpSet = new Set(this.scope) diff --git a/src/utils/YEvent.js b/src/utils/YEvent.js index cf8c6a4c..77c4603a 100644 --- a/src/utils/YEvent.js +++ b/src/utils/YEvent.js @@ -4,8 +4,7 @@ import { noAttributionsManager, YType, Doc, AbstractAttributionManager, Item, Transaction, AbstractStruct, // eslint-disable-line createAbsolutePositionFromRelativePosition, - createRelativePosition, - AbsolutePosition + createRelativePosition } from '../internals.js' import * as map from 'lib0/map' @@ -202,7 +201,7 @@ export const getPathTo = (parent, child, am = noAttributionsManager) => { } else { const parent = /** @type {import('../ytype.js').YType} */ (child._item.parent) // parent is array-ish - const apos = /** @type {AbsolutePosition} */ (createAbsolutePositionFromRelativePosition(createRelativePosition(parent, child._item.id), doc, false, am)) + const apos = /** @type {import('../utils/RelativePosition.js').AbsolutePosition} */ (createAbsolutePositionFromRelativePosition(createRelativePosition(parent, child._item.id), doc, false, am)) path.unshift(apos.index) } child = /** @type {YType} */ (child._item.parent) diff --git a/tests/IdMap.tests.js b/tests/IdMap.tests.js index 0d84e7d4..df6e2cb1 100644 --- a/tests/IdMap.tests.js +++ b/tests/IdMap.tests.js @@ -213,7 +213,7 @@ export const testUserAttributionEncodingBenchmark = tc => { idmap.insertIntoIdMap(attributions, idmap.createIdMapFromIdSet(tr.deleteSet, [createAttributionItem('delete', 'userX'), createAttributionItem('deleteAt', currentTime)])) currentTime += 1 }) - const ytext = ydoc.getText() + const ytext = ydoc.get() const N = 10000 t.measureTime(`time to attribute ${N / 1000}k changes`, () => { for (let i = 0; i < N; i++) { diff --git a/tests/compatibility.tests.js b/tests/compatibility.tests.js index 674d6862..0f3a343f 100644 --- a/tests/compatibility.tests.js +++ b/tests/compatibility.tests.js @@ -17,7 +17,7 @@ export const testArrayCompatibilityV1 = _tc => { const oldVal = JSON.parse('[[1,2,3,4],472,472,{"someprop":44},472,[1,2,3,4],{"someprop":44},[1,2,3,4],[1,2,3,4],[1,2,3,4],{"someprop":44},449,448,[1,2,3,4],[1,2,3,4],{"someprop":44},452,{"someprop":44},[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4],452,[1,2,3,4],497,{"someprop":44},497,497,497,{"someprop":44},[1,2,3,4],522,522,452,470,{"someprop":44},[1,2,3,4],453,{"someprop":44},480,480,480,508,508,508,[1,2,3,4],[1,2,3,4],502,492,492,453,{"someprop":44},496,496,496,[1,2,3,4],496,493,495,495,495,495,493,[1,2,3,4],493,493,453,{"someprop":44},{"someprop":44},505,505,517,517,505,[1,2,3,4],{"someprop":44},509,{"someprop":44},521,521,521,509,477,{"someprop":44},{"someprop":44},485,485,{"someprop":44},515,{"someprop":44},451,{"someprop":44},[1,2,3,4],516,516,516,516,{"someprop":44},499,499,469,469,[1,2,3,4],[1,2,3,4],512,512,512,{"someprop":44},454,487,487,487,[1,2,3,4],[1,2,3,4],454,[1,2,3,4],[1,2,3,4],{"someprop":44},[1,2,3,4],459,[1,2,3,4],513,459,{"someprop":44},[1,2,3,4],482,{"someprop":44},[1,2,3,4],[1,2,3,4],459,[1,2,3,4],{"someprop":44},[1,2,3,4],484,454,510,510,510,510,468,{"someprop":44},468,[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4],467,[1,2,3,4],467,486,486,486,[1,2,3,4],489,451,[1,2,3,4],{"someprop":44},[1,2,3,4],[1,2,3,4],{"someprop":44},{"someprop":44},483,[1,2,3,4],{"someprop":44},{"someprop":44},{"someprop":44},{"someprop":44},519,519,519,519,506,506,[1,2,3,4],{"someprop":44},464,{"someprop":44},481,481,[1,2,3,4],{"someprop":44},[1,2,3,4],464,475,475,475,463,{"someprop":44},[1,2,3,4],518,[1,2,3,4],[1,2,3,4],463,455,498,498,498,466,471,471,471,501,[1,2,3,4],501,501,476,{"someprop":44},466,[1,2,3,4],{"someprop":44},503,503,503,466,455,490,474,{"someprop":44},457,494,494,{"someprop":44},457,479,{"someprop":44},[1,2,3,4],500,500,500,{"someprop":44},[1,2,3,4],[1,2,3,4],{"someprop":44},{"someprop":44},{"someprop":44},[1,2,3,4],[1,2,3,4],{"someprop":44},[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3],491,491,[1,2,3,4],504,504,504,504,465,[1,2,3,4],{"someprop":44},460,{"someprop":44},488,488,488,[1,2,3,4],[1,2,3,4],{"someprop":44},{"someprop":44},514,514,514,514,{"someprop":44},{"someprop":44},{"someprop":44},458,[1,2,3,4],[1,2,3,4],462,[1,2,3,4],[1,2,3,4],{"someprop":44},462,{"someprop":44},[1,2,3,4],{"someprop":44},[1,2,3,4],507,{"someprop":44},{"someprop":44},507,507,{"someprop":44},{"someprop":44},[1,2,3,4],{"someprop":44},461,{"someprop":44},473,461,[1,2,3,4],461,511,511,461,{"someprop":44},{"someprop":44},520,520,520,[1,2,3,4],458]') const doc = new Y.Doc() Y.applyUpdate(doc, buffer.fromBase64(oldDoc)) - t.compare(doc.getArray('array').toJSON(), oldVal) + t.compare(doc.get('array').toJSON().children, oldVal) } /** @@ -29,7 +29,7 @@ export const testMapDecodingCompatibilityV1 = _tc => { const oldVal = /** @type {any} */ ({"one":[1,2,3,4],"two":{"deepkey":"deepvalue"}}) const doc = new Y.Doc() Y.applyUpdate(doc, buffer.fromBase64(oldDoc)) - t.compare(doc.getMap('map').toJSON(), oldVal) + t.compare(doc.get('map').toJSON().children, oldVal) } /** @@ -41,5 +41,5 @@ export const testTextDecodingCompatibilityV1 = _tc => { const oldVal = [{"insert":"1306rup"},{"insert":"uj","format":{"italic":true,"color":"#888"}},{"insert":"ikkcjnrcpsckw1319bccgkp\n"},{"insert":"\n1131","format":{"bold":true}},{"insert":"1326rpcznqahopcrtd","format":{"italic":true}},{"insert":"3axhkthhu","format":{"bold":true}},{"insert":"28"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"9"},{"insert":"04ku","format":{"italic":true}},{"insert":"1323nucvxsqlznwlfavmpc\nu"},{"insert":"tc","format":{"italic":true}},{"insert":"je1318jwskjabdndrdlmjae\n1293tj\nj1292qrmf"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"k\nuf"},{"insert":"14hs","format":{"italic":true}},{"insert":"13dccxdyxg"},{"insert":"zc","format":{"italic":true,"color":"#888"}},{"insert":"apo"},{"insert":"tn","format":{"bold":true}},{"insert":"r"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"gn\n"},{"insert":"z","format":{"italic":true}},{"insert":"\n121"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"291311kk9zjznywohpx"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"cnbrcaq\n"},{"insert":"1","format":{"italic":true,"color":"#888"}},{"insert":"1310g"},{"insert":"ws","format":{"italic":true,"color":"#888"}},{"insert":"hxwych"},{"insert":"kq","format":{"italic":true}},{"insert":"sdru1320cohbvcrkrpjngdoc\njqic\n"},{"insert":"2","format":{"italic":true,"color":"#888"}},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"90n1297zm"},{"insert":"v1309zlgvjx","format":{"bold":true}},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"g","format":{"bold":true}},{"insert":"1314pycavu","format":{"italic":true,"color":"#888"}},{"insert":"pkzqcj"},{"insert":"sa","format":{"italic":true,"color":"#888"}},{"insert":"sjy\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"xr\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"},{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}, {"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"1"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"1295qfrvlyfap201312qrwt"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"b1322rnbaokorixenvp\nrxq"},{"insert":"j","format":{"italic":true}},{"insert":"x","format":{"italic":true,"color":"#888"}},{"insert":"15mziwabzkrrmscvdovao\n0","format":{"italic":true}},{"insert":"hx","format":{"italic":true,"bold":true}},{"insert":"ojeetrjhxkr13031317pfcyhksrkpkt\nuhv1","format":{"italic":true}},{"insert":"32","format":{"italic":true,"color":"#888"}},{"insert":"4rorywthq1325iodbzizxhmlibvpyrxmq\n\nganln\nqne\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"dvf"},{"insert":"ac","format":{"bold":true}},{"insert":"1302xciwa"},{"insert":"1305rl","format":{"bold":true}},{"insert":"08\n"},{"insert":"eyk","format":{"bold":true}},{"insert":"y1321apgivydqsjfsehhezukiqtt1307tvjiejlh"},{"insert":"1316zlpkmctoqomgfthbpg","format":{"bold":true}},{"insert":"gv"},{"insert":"lb","format":{"bold":true}},{"insert":"f\nhntk\njv1uu\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]}].map(x => ({ type: 'insert', ...x })) const doc = new Y.Doc() Y.applyUpdate(doc, buffer.fromBase64(oldDoc)) - t.compare(doc.getText('text').getContent().toJSON().children, /** @type {any} */ (oldVal)) + t.compare(doc.get('text').getContent().toJSON().children, /** @type {any} */ (oldVal)) } diff --git a/tests/doc.tests.js b/tests/doc.tests.js index 8a9145f7..ef93fc85 100644 --- a/tests/doc.tests.js +++ b/tests/doc.tests.js @@ -29,10 +29,9 @@ export const testFindTypeInOtherDoc = _tc => { const ydocClone = new Y.Doc() Y.applyUpdate(ydocClone, Y.encodeStateAsUpdate(ydoc)) /** - * @template {Y.Type} Type - * @param {Type} ytype + * @param {Y.Type} ytype * @param {Y.Doc} otherYdoc - * @return {Type} + * @return {Y.Type} */ const findTypeInOtherYdoc = (ytype, otherYdoc) => { const ydoc = /** @type {Y.Doc} */ (ytype.doc) @@ -47,7 +46,7 @@ export const testFindTypeInOtherDoc = _tc => { if (rootKey == null) { throw new Error('type does not exist in other ydoc') } - return /** @type {Type} */ (otherYdoc.get(rootKey, /** @type {import('../src/utils/ts.js').YTypeConstructors} */ (ytype.constructor))) + return otherYdoc.get(rootKey) } else { /** * If it is a sub type, we use the item id to find the history type. @@ -60,7 +59,7 @@ export const testFindTypeInOtherDoc = _tc => { ) const otherItem = /** @type {Y.Item} */ (otherStructs[itemIndex]) const otherContent = /** @type {Y.ContentType} */ (otherItem.content) - return /** @type {Type} */ (otherContent.type) + return /** @type {Y.Type} */ (otherContent.type) } } t.assert(findTypeInOtherYdoc(ymap, ydocClone) != null) @@ -78,7 +77,7 @@ export const testClientIdDuplicateChange = _tc => { const doc2 = new Y.Doc() doc2.clientID = 0 t.assert(doc2.clientID === doc1.clientID) - doc1.getArray('a').insert(0, [1, 2]) + doc1.get('a').insert(0, [1, 2]) Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc1)) t.assert(doc2.clientID !== doc1.clientID) } @@ -88,12 +87,12 @@ export const testClientIdDuplicateChange = _tc => { */ export const testGetTypeEmptyId = _tc => { const doc1 = new Y.Doc() - doc1.getText('').insert(0, 'h') - doc1.getText().insert(1, 'i') + doc1.get('').insert(0, 'h') + doc1.get().insert(1, 'i') const doc2 = new Y.Doc() Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc1)) - t.assert(doc2.getText().toString() === 'hi') - t.assert(doc2.getText('').toString() === 'hi') + t.assert(doc2.get().toString() === 'hi') + t.assert(doc2.get('').toString() === 'hi') } /** @@ -103,14 +102,14 @@ export const testToJSON = _tc => { const doc = new Y.Doc() t.compare(doc.toJSON(), {}, 'doc.toJSON yields empty object') - const arr = doc.getArray('array') + const arr = doc.get('array') arr.push(['test1']) - const map = doc.getMap('map') - map.set('k1', 'v1') - const map2 = new Y.Map() - map.set('k2', map2) - map2.set('m2k1', 'm2v1') + const map = doc.get('map') + map.setAttr('k1', 'v1') + const map2 = new Y.Type() + map.setAttr('k2', map2) + map2.setAttr('m2k1', 'm2v1') t.compare(doc.toJSON(), { array: ['test1'], @@ -137,30 +136,30 @@ export const testSubdoc = _tc => { doc.on('subdocs', subdocs => { event = [Array.from(subdocs.added).map(x => x.guid), Array.from(subdocs.removed).map(x => x.guid), Array.from(subdocs.loaded).map(x => x.guid)] }) - const subdocs = doc.getMap('mysubdocs') + const subdocs = doc.get('mysubdocs') const docA = new Y.Doc({ guid: 'a' }) docA.load() - subdocs.set('a', docA) + subdocs.setAttr('a', docA) t.compare(event, [['a'], [], ['a']]) event = null - subdocs.get('a').load() + subdocs.getAttr('a').load() t.assert(event === null) event = null - subdocs.get('a').destroy() + subdocs.getAttr('a').destroy() t.compare(event, [['a'], ['a'], []]) - subdocs.get('a').load() + subdocs.getAttr('a').load() t.compare(event, [[], [], ['a']]) - subdocs.set('b', new Y.Doc({ guid: 'a', shouldLoad: false })) + subdocs.setAttr('b', new Y.Doc({ guid: 'a', shouldLoad: false })) t.compare(event, [['a'], [], []]) - subdocs.get('b').load() + subdocs.getAttr('b').load() t.compare(event, [[], [], ['a']]) const docC = new Y.Doc({ guid: 'c' }) docC.load() - subdocs.set('c', docC) + subdocs.setAttr('c', docC) t.compare(event, [['c'], [], ['c']]) t.compare(Array.from(doc.getSubdocGuids()), ['a', 'c']) @@ -179,12 +178,12 @@ export const testSubdoc = _tc => { Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc)) t.compare(event, [['a', 'a', 'c'], [], []]) - doc2.getMap('mysubdocs').get('a').load() + doc2.get('mysubdocs').getAttr('a').load() t.compare(event, [[], [], ['a']]) t.compare(Array.from(doc2.getSubdocGuids()), ['a', 'c']) - doc2.getMap('mysubdocs').delete('a') + doc2.get('mysubdocs').deleteAttr('a') t.compare(event, [[], ['a'], []]) t.compare(Array.from(doc2.getSubdocGuids()), ['a', 'c']) } @@ -195,7 +194,7 @@ export const testSubdoc = _tc => { */ export const testSubdocLoadEdgeCases = _tc => { const ydoc = new Y.Doc() - const yarray = ydoc.getArray() + const yarray = ydoc.get() const subdoc1 = new Y.Doc() /** * @type {any} @@ -225,7 +224,7 @@ export const testSubdocLoadEdgeCases = _tc => { lastEvent = event }) Y.applyUpdate(ydoc2, Y.encodeStateAsUpdate(ydoc)) - const subdoc3 = ydoc2.getArray().get(0) + const subdoc3 = ydoc2.get().get(0) t.assert(subdoc3.shouldLoad === false) t.assert(subdoc3.autoLoad === false) t.assert(lastEvent !== null && lastEvent.added.has(subdoc3)) @@ -242,7 +241,7 @@ export const testSubdocLoadEdgeCases = _tc => { */ export const testSubdocLoadEdgeCasesAutoload = _tc => { const ydoc = new Y.Doc() - const yarray = ydoc.getArray() + const yarray = ydoc.get() const subdoc1 = new Y.Doc({ autoLoad: true }) /** * @type {any} @@ -272,7 +271,7 @@ export const testSubdocLoadEdgeCasesAutoload = _tc => { lastEvent = event }) Y.applyUpdate(ydoc2, Y.encodeStateAsUpdate(ydoc)) - const subdoc3 = ydoc2.getArray().get(0) + const subdoc3 = ydoc2.get().get(0) t.assert(subdoc1.shouldLoad) t.assert(subdoc1.autoLoad) t.assert(lastEvent !== null && lastEvent.added.has(subdoc3)) @@ -284,7 +283,7 @@ export const testSubdocLoadEdgeCasesAutoload = _tc => { */ export const testSubdocsUndo = _tc => { const ydoc = new Y.Doc() - const elems = ydoc.getXmlFragment() + const elems = ydoc.get() const undoManager = new Y.UndoManager(elems) const subdoc = new Y.Doc() // @ts-ignore diff --git a/tests/encoding.tests.js b/tests/encoding.tests.js index 3e444f45..e1c692f7 100644 --- a/tests/encoding.tests.js +++ b/tests/encoding.tests.js @@ -42,12 +42,12 @@ export const testDiffStateVectorOfUpdateIsEmpty = _tc => { * @type {any} */ let sv = null - ydoc.getText().insert(0, 'a') + ydoc.get().insert(0, 'a') ydoc.on('update', update => { sv = Y.encodeStateVectorFromUpdate(update) }) // should produce an update with an empty state vector (because previous ops are missing) - ydoc.getText().insert(0, 'a') + ydoc.get().insert(0, 'a') t.assert(sv !== null && sv.byteLength === 1 && sv[0] === 0) } @@ -64,9 +64,9 @@ export const testDiffStateVectorOfUpdateIgnoresSkips = _tc => { ydoc.on('update', update => { updates.push(update) }) - ydoc.getText().insert(0, 'a') - ydoc.getText().insert(0, 'b') - ydoc.getText().insert(0, 'c') + ydoc.get().insert(0, 'a') + ydoc.get().insert(0, 'b') + ydoc.get().insert(0, 'c') const update13 = Y.mergeUpdates([updates[0], updates[2]]) const sv = Y.encodeStateVectorFromUpdate(update13) const state = Y.decodeStateVector(sv) diff --git a/tests/relativePositions.tests.js b/tests/relativePositions.tests.js index 75e7088d..87226ed0 100644 --- a/tests/relativePositions.tests.js +++ b/tests/relativePositions.tests.js @@ -2,7 +2,7 @@ import * as Y from '../src/index.js' import * as t from 'lib0/testing' /** - * @param {Y.Text} ytext + * @param {Y.Type<{text:true}>} ytext */ const checkRelativePositions = ytext => { // test if all positions are encoded and restored correctly @@ -20,11 +20,11 @@ const checkRelativePositions = ytext => { } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionCase1 = tc => { +export const testRelativePositionCase1 = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() ytext.insert(0, '1') ytext.insert(0, 'abc') ytext.insert(0, 'z') @@ -34,21 +34,21 @@ export const testRelativePositionCase1 = tc => { } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionCase2 = tc => { +export const testRelativePositionCase2 = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() ytext.insert(0, 'abc') checkRelativePositions(ytext) } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionCase3 = tc => { +export const testRelativePositionCase3 = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() ytext.insert(0, 'abc') ytext.insert(0, '1') ytext.insert(0, 'xyz') @@ -56,43 +56,43 @@ export const testRelativePositionCase3 = tc => { } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionCase4 = tc => { +export const testRelativePositionCase4 = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() ytext.insert(0, '1') checkRelativePositions(ytext) } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionCase5 = tc => { +export const testRelativePositionCase5 = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() ytext.insert(0, '2') ytext.insert(0, '1') checkRelativePositions(ytext) } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionCase6 = tc => { +export const testRelativePositionCase6 = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() checkRelativePositions(ytext) } /** * Testing https://github.com/yjs/yjs/issues/657 * - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionCase7 = tc => { +export const testRelativePositionCase7 = _tc => { const docA = new Y.Doc() - const textA = docA.getText('text') + const textA = docA.get('text') textA.insert(0, 'abcde') // Create a relative position at index 2 in 'textA' const relativePosition = Y.createRelativePositionFromTypeIndex(textA, 2) @@ -106,11 +106,11 @@ export const testRelativePositionCase7 = tc => { } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionAssociationDifference = tc => { +export const testRelativePositionAssociationDifference = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() ytext.insert(0, '2') ytext.insert(0, '1') const rposRight = Y.createRelativePositionFromTypeIndex(ytext, 1, 0) @@ -123,11 +123,11 @@ export const testRelativePositionAssociationDifference = tc => { } /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testRelativePositionWithUndo = tc => { +export const testRelativePositionWithUndo = _tc => { const ydoc = new Y.Doc() - const ytext = ydoc.getText() + const ytext = ydoc.get() ytext.insert(0, 'hello world') const rpos = Y.createRelativePositionFromTypeIndex(ytext, 1) const um = new Y.UndoManager(ytext) diff --git a/tests/snapshot.tests.js b/tests/snapshot.tests.js index 2ccce441..11fecf34 100644 --- a/tests/snapshot.tests.js +++ b/tests/snapshot.tests.js @@ -1,17 +1,18 @@ import * as Y from '../src/index.js' import * as t from 'lib0/testing' import { init } from './testHelper.js' +import * as delta from 'lib0/delta' /** * @param {t.TestCase} _tc */ export const testBasic = _tc => { const ydoc = new Y.Doc({ gc: false }) - ydoc.getText().insert(0, 'world!') + ydoc.get().insert(0, 'world!') const snapshot = Y.snapshot(ydoc) - ydoc.getText().insert(0, 'hello ') + ydoc.get().insert(0, 'hello ') const restored = Y.createDocFromSnapshot(ydoc, snapshot) - t.assert(restored.getText().toString() === 'world!') + t.assert(restored.get().getContent().equals(delta.create().insert('world!'))) } /** @@ -19,7 +20,7 @@ export const testBasic = _tc => { */ export const testBasicXmlAttributes = _tc => { const ydoc = new Y.Doc({ gc: false }) - const yxml = ydoc.getMap().set('el', new Y.XmlElement('div')) + const yxml = ydoc.get().setAttr('el', new Y.Type('div')) const snapshot1 = Y.snapshot(ydoc) yxml.setAttribute('a', '1') const snapshot2 = Y.snapshot(ydoc) @@ -34,14 +35,14 @@ export const testBasicXmlAttributes = _tc => { */ export const testBasicRestoreSnapshot = _tc => { const doc = new Y.Doc({ gc: false }) - doc.getArray('array').insert(0, ['hello']) + doc.get('array').insert(0, ['hello']) const snap = Y.snapshot(doc) - doc.getArray('array').insert(1, ['world']) + doc.get('array').insert(1, ['world']) const docRestored = Y.createDocFromSnapshot(doc, snap) - t.compare(docRestored.getArray('array').toArray(), ['hello']) - t.compare(doc.getArray('array').toArray(), ['hello', 'world']) + t.compare(docRestored.get('array').toArray(), ['hello']) + t.compare(doc.get('array').toJSON().children, ['hello', 'world']) } /** @@ -51,17 +52,17 @@ export const testEmptyRestoreSnapshot = _tc => { const doc = new Y.Doc({ gc: false }) const snap = Y.snapshot(doc) snap.sv.set(9999, 0) - doc.getArray().insert(0, ['world']) + doc.get().insert(0, ['world']) const docRestored = Y.createDocFromSnapshot(doc, snap) - t.compare(docRestored.getArray().toArray(), []) - t.compare(doc.getArray().toArray(), ['world']) + t.compare(docRestored.get().toArray(), []) + t.compare(doc.get().toArray(), ['world']) // now this snapshot reflects the latest state. It should still work. const snap2 = Y.snapshot(doc) const docRestored2 = Y.createDocFromSnapshot(doc, snap2) - t.compare(docRestored2.getArray().toArray(), ['world']) + t.compare(docRestored2.get().toArray(), ['world']) } /** @@ -69,8 +70,8 @@ export const testEmptyRestoreSnapshot = _tc => { */ export const testRestoreSnapshotWithSubType = _tc => { const doc = new Y.Doc({ gc: false }) - doc.getArray('array').insert(0, [new Y.Map()]) - const subMap = doc.getArray('array').get(0) + doc.get('array').insert(0, [new Y.Type()]) + const subMap = doc.get('array').get(0) subMap.set('key1', 'value1') const snap = Y.snapshot(doc) @@ -78,10 +79,10 @@ export const testRestoreSnapshotWithSubType = _tc => { const docRestored = Y.createDocFromSnapshot(doc, snap) - t.compare(docRestored.getArray('array').toJSON(), [{ + t.compare(docRestored.get('array').toJSON().children, [{ key1: 'value1' }]) - t.compare(doc.getArray('array').toJSON(), [{ + t.compare(doc.get('array').toJSON().children, [{ key1: 'value1', key2: 'value2' }]) @@ -92,15 +93,15 @@ export const testRestoreSnapshotWithSubType = _tc => { */ export const testRestoreDeletedItem1 = _tc => { const doc = new Y.Doc({ gc: false }) - doc.getArray('array').insert(0, ['item1', 'item2']) + doc.get('array').insert(0, ['item1', 'item2']) const snap = Y.snapshot(doc) - doc.getArray('array').delete(0) + doc.get('array').delete(0) const docRestored = Y.createDocFromSnapshot(doc, snap) - t.compare(docRestored.getArray('array').toArray(), ['item1', 'item2']) - t.compare(doc.getArray('array').toArray(), ['item2']) + t.compare(docRestored.get('array').toArray(), ['item1', 'item2']) + t.compare(doc.get('array').toArray(), ['item2']) } /** @@ -108,17 +109,17 @@ export const testRestoreDeletedItem1 = _tc => { */ export const testRestoreLeftItem = _tc => { const doc = new Y.Doc({ gc: false }) - doc.getArray('array').insert(0, ['item1']) - doc.getMap('map').set('test', 1) - doc.getArray('array').insert(0, ['item0']) + doc.get('array').insert(0, ['item1']) + doc.get('map').setAttr('test', 1) + doc.get('array').insert(0, ['item0']) const snap = Y.snapshot(doc) - doc.getArray('array').delete(1) + doc.get('array').delete(1) const docRestored = Y.createDocFromSnapshot(doc, snap) - t.compare(docRestored.getArray('array').toArray(), ['item0', 'item1']) - t.compare(doc.getArray('array').toArray(), ['item0']) + t.compare(docRestored.get('array').toArray(), ['item0', 'item1']) + t.compare(doc.get('array').toArray(), ['item0']) } /** @@ -126,15 +127,15 @@ export const testRestoreLeftItem = _tc => { */ export const testDeletedItemsBase = _tc => { const doc = new Y.Doc({ gc: false }) - doc.getArray('array').insert(0, ['item1']) - doc.getArray('array').delete(0) + doc.get('array').insert(0, ['item1']) + doc.get('array').delete(0) const snap = Y.snapshot(doc) - doc.getArray('array').insert(0, ['item0']) + doc.get('array').insert(0, ['item0']) const docRestored = Y.createDocFromSnapshot(doc, snap) - t.compare(docRestored.getArray('array').toArray(), []) - t.compare(doc.getArray('array').toArray(), ['item0']) + t.compare(docRestored.get('array').toArray(), []) + t.compare(doc.get('array').toArray(), ['item0']) } /** @@ -142,15 +143,15 @@ export const testDeletedItemsBase = _tc => { */ export const testDeletedItems2 = _tc => { const doc = new Y.Doc({ gc: false }) - doc.getArray('array').insert(0, ['item1', 'item2', 'item3']) - doc.getArray('array').delete(1) + doc.get('array').insert(0, ['item1', 'item2', 'item3']) + doc.get('array').delete(1) const snap = Y.snapshot(doc) - doc.getArray('array').insert(0, ['item0']) + doc.get('array').insert(0, ['item0']) const docRestored = Y.createDocFromSnapshot(doc, snap) - t.compare(docRestored.getArray('array').toArray(), ['item1', 'item3']) - t.compare(doc.getArray('array').toArray(), ['item0', 'item1', 'item3']) + t.compare(docRestored.get('array').toArray(), ['item1', 'item3']) + t.compare(doc.get('array').toArray(), ['item0', 'item1', 'item3']) } /** @@ -191,10 +192,10 @@ export const testDependentChanges = tc => { testConnector.syncAll() const docRestored0 = Y.createDocFromSnapshot(array0.doc, snap) - t.compare(docRestored0.getArray('array').toArray(), ['user1item1', 'user2item1']) + t.compare(docRestored0.get('array').toArray(), ['user1item1', 'user2item1']) const docRestored1 = Y.createDocFromSnapshot(array1.doc, snap) - t.compare(docRestored1.getArray('array').toArray(), ['user1item1', 'user2item1']) + t.compare(docRestored1.get('array').toArray(), ['user1item1', 'user2item1']) } /** @@ -209,7 +210,7 @@ export const testContainsUpdate = _tc => { ydoc.on('update', update => { updates.push(update) }) - const yarr = ydoc.getArray() + const yarr = ydoc.get() const snapshot1 = Y.snapshot(ydoc) yarr.insert(0, [1]) const snapshot2 = Y.snapshot(ydoc) diff --git a/tests/testHelper.js b/tests/testHelper.js index 409481a3..88dedeb8 100644 --- a/tests/testHelper.js +++ b/tests/testHelper.js @@ -468,8 +468,6 @@ export const compare = users => { t.assert(u.store.pendingDs === null) t.assert(u.store.pendingStructs === null) } - // Test Array iterator - t.compare(users[0].get('array').toArray(), Array.from(users[0].get('array'))) // Test Map iterator const ymapkeys = Array.from(users[0].get('map').attrKeys()) t.assert(ymapkeys.length === Object.keys(userMapValues[0]).length) @@ -478,8 +476,10 @@ export const compare = users => { * @type {Object} */ const mapRes = {} - for (const [k, v] of users[0].get('map')) { - mapRes[k] = v instanceof Y.AbstractType ? v.toJSON() : v + const attrs0 = users[0].get('map').getAttrs() + for (const k in attrs0) { + const v = attrs0[k] + mapRes[k] = v instanceof Y.Type ? v.toJSON() : v } t.compare(userMapValues[0], mapRes) // Compare all users diff --git a/tests/undo-redo.tests.js b/tests/undo-redo.tests.js index a1e3acf7..dda9f79d 100644 --- a/tests/undo-redo.tests.js +++ b/tests/undo-redo.tests.js @@ -8,14 +8,14 @@ export const testInconsistentFormat = () => { * @param {Y.Doc} ydoc */ const testYjsMerge = ydoc => { - const content = /** @type {Y.XmlText} */ (ydoc.get('text', Y.XmlText)) + const content = ydoc.get('text') content.format(0, 6, { bold: null }) content.format(6, 4, { type: 'text' }) t.compare(content.getContent(), delta.create().insert('Merge Test', { type: 'text' }).insert(' After', { type: 'text', italic: true }).done()) } const initializeYDoc = () => { const yDoc = new Y.Doc({ gc: false }) - const content = /** @type {Y.XmlText} */ (yDoc.get('text', Y.XmlText)) + const content = yDoc.get('text') content.insert(0, ' After', { type: 'text', italic: true }) content.insert(0, 'Test', { type: 'text' }) content.insert(0, 'Merge ', { type: 'text', bold: true }) @@ -99,7 +99,7 @@ export const testUndoText = tc => { export const testEmptyTypeScope = _tc => { const ydoc = new Y.Doc() const um = new Y.UndoManager([], { doc: ydoc }) - const yarray = ydoc.getArray() + const yarray = ydoc.get() um.addToScope(yarray) yarray.insert(0, [1]) um.undo() @@ -111,15 +111,15 @@ export const testEmptyTypeScope = _tc => { */ export const testRejectUpdateExample = _tc => { const tmpydoc1 = new Y.Doc() - tmpydoc1.getArray('restricted').insert(0, [1]) - tmpydoc1.getArray('public').insert(0, [1]) + tmpydoc1.get('restricted').insert(0, [1]) + tmpydoc1.get('public').insert(0, [1]) const update1 = Y.encodeStateAsUpdate(tmpydoc1) const tmpydoc2 = new Y.Doc() - tmpydoc2.getArray('public').insert(0, [2]) + tmpydoc2.get('public').insert(0, [2]) const update2 = Y.encodeStateAsUpdate(tmpydoc2) const ydoc = new Y.Doc() - const restrictedType = ydoc.getArray('restricted') + const restrictedType = ydoc.get('restricted') /** * Assume this function handles incoming updates via a communication channel like websockets. @@ -156,7 +156,7 @@ export const testRejectUpdateExample = _tc => { updateHandler(update1) updateHandler(update2) t.assert(restrictedType.length === 0) - t.assert(ydoc.getArray('public').length === 2) + t.assert(ydoc.get('public').length === 2) } /** @@ -166,7 +166,7 @@ export const testRejectUpdateExample = _tc => { export const testGlobalScope = _tc => { const ydoc = new Y.Doc() const um = new Y.UndoManager(ydoc) - const yarray = ydoc.getArray() + const yarray = ydoc.get() yarray.insert(0, [1]) um.undo() t.assert(yarray.length === 0) @@ -178,7 +178,7 @@ export const testGlobalScope = _tc => { */ export const testDoubleUndo = _tc => { const doc = new Y.Doc() - const text = doc.getText() + const text = doc.get() text.insert(0, '1221') const manager = new Y.UndoManager(text) @@ -199,39 +199,39 @@ export const testDoubleUndo = _tc => { */ export const testUndoMap = tc => { const { testConnector, map0, map1 } = init(tc, { users: 2 }) - map0.set('a', 0) + map0.setAttr('a', 0) const undoManager = new Y.UndoManager(map0) - map0.set('a', 1) + map0.setAttr('a', 1) undoManager.undo() - t.assert(map0.get('a') === 0) + t.assert(map0.getAttr('a') === 0) undoManager.redo() - t.assert(map0.get('a') === 1) + t.assert(map0.getAttr('a') === 1) // testing sub-types and if it can restore a whole type - const subType = new Y.Map() - map0.set('a', subType) - subType.set('x', 42) + const subType = new Y.Type() + map0.setAttr('a', subType) + subType.setAttr('x', 42) t.compare(map0.toJSON(), /** @type {any} */ ({ a: { x: 42 } })) undoManager.undo() - t.assert(map0.get('a') === 1) + t.assert(map0.getAttr('a') === 1) undoManager.redo() t.compare(map0.toJSON(), /** @type {any} */ ({ a: { x: 42 } })) testConnector.syncAll() // if content is overwritten by another user, undo operations should be skipped - map1.set('a', 44) + map1.setAttr('a', 44) testConnector.syncAll() undoManager.undo() - t.assert(map0.get('a') === 44) + t.assert(map0.getAttr('a') === 44) undoManager.redo() - t.assert(map0.get('a') === 44) + t.assert(map0.getAttr('a') === 44) // test setting value multiple times - map0.set('b', 'initial') + map0.setAttr('b', 'initial') undoManager.stopCapturing() - map0.set('b', 'val1') - map0.set('b', 'val2') + map0.setAttr('b', 'val1') + map0.setAttr('b', 'val2') undoManager.stopCapturing() undoManager.undo() - t.assert(map0.get('b') === 'initial') + t.assert(map0.getAttr('b') === 'initial') } /** @@ -257,32 +257,32 @@ export const testUndoArray = tc => { t.compare(array0.toArray(), [2, 3, 4, 5, 6]) array0.delete(0, 5) // test nested structure - const ymap = new Y.Map() + const ymap = new Y.Type() array0.insert(0, [ymap]) - t.compare(array0.toJSON(), [{}]) + t.compare(array0.toJSON().children, [{}]) undoManager.stopCapturing() - ymap.set('a', 1) - t.compare(array0.toJSON(), [{ a: 1 }]) + ymap.setAttr('a', 1) + t.compare(array0.toJSON().children, [{ a: 1 }]) undoManager.undo() - t.compare(array0.toJSON(), [{}]) + t.compare(array0.toJSON().children, [{}]) undoManager.undo() - t.compare(array0.toJSON(), [2, 3, 4, 5, 6]) + t.compare(array0.toJSON().children, [2, 3, 4, 5, 6]) undoManager.redo() - t.compare(array0.toJSON(), [{}]) + t.compare(array0.toJSON().children, [{}]) undoManager.redo() - t.compare(array0.toJSON(), [{ a: 1 }]) + t.compare(array0.toJSON().children, [{ a: 1 }]) testConnector.syncAll() array1.get(0).set('b', 2) testConnector.syncAll() - t.compare(array0.toJSON(), [{ a: 1, b: 2 }]) + t.compare(array0.toJSON().children, [{ a: 1, b: 2 }]) undoManager.undo() - t.compare(array0.toJSON(), [{ b: 2 }]) + t.compare(array0.toJSON().children, [{ b: 2 }]) undoManager.undo() - t.compare(array0.toJSON(), [2, 3, 4, 5, 6]) + t.compare(array0.toJSON().children, [2, 3, 4, 5, 6]) undoManager.redo() - t.compare(array0.toJSON(), [{ b: 2 }]) + t.compare(array0.toJSON().children, [{ b: 2 }]) undoManager.redo() - t.compare(array0.toJSON(), [{ a: 1, b: 2 }]) + t.compare(array0.toJSON().children, [{ a: 1, b: 2 }]) } /** @@ -291,11 +291,10 @@ export const testUndoArray = tc => { export const testUndoXml = tc => { const { xml0 } = init(tc, { users: 3 }) const undoManager = new Y.UndoManager(xml0) - const child = new Y.XmlElement('p') + const child = new Y.Type('p') xml0.insert(0, [child]) - const textchild = new Y.XmlText('content') + const textchild = new Y.Type('content') child.insert(0, [textchild]) - t.assert(xml0.toString() === '

content

') // format textchild and revert that change undoManager.stopCapturing() textchild.format(3, 4, { bold: true }) @@ -358,8 +357,8 @@ export const testTrackClass = tc => { export const testTypeScope = tc => { const { array0 } = init(tc, { users: 3 }) // only track origins that are numbers - const text0 = new Y.Text() - const text1 = new Y.Text() + const text0 = new Y.Type() + const text1 = new Y.Type() array0.insert(0, [text0, text1]) const undoManager = new Y.UndoManager(text0) const undoManagerBoth = new Y.UndoManager([text0, text1]) @@ -379,9 +378,9 @@ export const testTypeScope = tc => { export const testUndoInEmbed = tc => { const { text0 } = init(tc, { users: 3 }) const undoManager = new Y.UndoManager(text0) - const nestedText = new Y.Text('initial text') + const nestedText = new Y.Type('initial text') undoManager.stopCapturing() - text0.insertEmbed(0, nestedText, { bold: true }) + text0.insert(0, [nestedText], { bold: true }) t.assert(nestedText.toString() === 'initial text') undoManager.stopCapturing() nestedText.delete(0, nestedText.length) @@ -397,14 +396,11 @@ export const testUndoInEmbed = tc => { * @param {t.TestCase} tc */ export const testUndoDeleteFilter = tc => { - /** - * @type {Y.Array} - */ - const array0 = /** @type {any} */ (init(tc, { users: 3 }).array0) + const array0 = init(tc, { users: 3 }).array0 const undoManager = new Y.UndoManager(array0, { deleteFilter: item => !(item instanceof Y.Item) || (item.content instanceof Y.ContentType && item.content.type._map.size === 0) }) - const map0 = new Y.Map() - map0.set('hi', 1) - const map1 = new Y.Map() + const map0 = new Y.Type() + map0.setAttr('hi', 1) + const map1 = new Y.Type() array0.insert(0, [map0, map1]) undoManager.undo() t.assert(array0.length === 1) @@ -422,25 +418,25 @@ export const testUndoUntilChangePerformed = _tc => { doc.on('update', update => Y.applyUpdate(doc2, update)) doc2.on('update', update => Y.applyUpdate(doc, update)) - const yArray = doc.getArray('array') - const yArray2 = doc2.getArray('array') - const yMap = new Y.Map() - yMap.set('hello', 'world') + const yArray = doc.get('array') + const yArray2 = doc2.get('array') + const yMap = new Y.Type() + yMap.setAttr('hello', 'world') yArray.push([yMap]) - const yMap2 = new Y.Map() - yMap2.set('key', 'value') + const yMap2 = new Y.Type() + yMap2.setAttr('key', 'value') yArray.push([yMap2]) const undoManager = new Y.UndoManager([yArray], { trackedOrigins: new Set([doc.clientID]) }) const undoManager2 = new Y.UndoManager([doc2.get('array')], { trackedOrigins: new Set([doc2.clientID]) }) - Y.transact(doc, () => yMap2.set('key', 'value modified'), doc.clientID) + Y.transact(doc, () => yMap2.setAttr('key', 'value modified'), doc.clientID) undoManager.stopCapturing() - Y.transact(doc, () => yMap.set('hello', 'world modified'), doc.clientID) + Y.transact(doc, () => yMap.setAttr('hello', 'world modified'), doc.clientID) Y.transact(doc2, () => yArray2.delete(0), doc2.clientID) undoManager2.undo() undoManager.undo() - t.compareStrings(yMap2.get('key'), 'value') + t.compareStrings(yMap2.getAttr('key'), 'value') } /** @@ -449,53 +445,50 @@ export const testUndoUntilChangePerformed = _tc => { */ export const testUndoNestedUndoIssue = _tc => { const doc = new Y.Doc({ gc: false }) - const design = doc.getMap() + const design = doc.get() const undoManager = new Y.UndoManager(design, { captureTimeout: 0 }) - /** - * @type {Y.Map} - */ - const text = new Y.Map() + const text = new Y.Type() - const blocks1 = new Y.Array() - const blocks1block = new Y.Map() + const blocks1 = new Y.Type() + const blocks1block = new Y.Type() doc.transact(() => { - blocks1block.set('text', 'Type Something') + blocks1block.setAttr('text', 'Type Something') blocks1.push([blocks1block]) - text.set('blocks', blocks1block) - design.set('text', text) + text.setAttr('blocks', blocks1block) + design.setAttr('text', text) }) - const blocks2 = new Y.Array() - const blocks2block = new Y.Map() + const blocks2 = new Y.Type() + const blocks2block = new Y.Type() doc.transact(() => { - blocks2block.set('text', 'Something') + blocks2block.setAttr('text', 'Something') blocks2.push([blocks2block]) - text.set('blocks', blocks2block) + text.setAttr('blocks', blocks2block) }) - const blocks3 = new Y.Array() - const blocks3block = new Y.Map() + const blocks3 = new Y.Type() + const blocks3block = new Y.Type() doc.transact(() => { - blocks3block.set('text', 'Something Else') + blocks3block.setAttr('text', 'Something Else') blocks3.push([blocks3block]) - text.set('blocks', blocks3block) + text.setAttr('blocks', blocks3block) }) - t.compare(design.toJSON(), { text: { blocks: { text: 'Something Else' } } }) + t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something Else' } } }) undoManager.undo() - t.compare(design.toJSON(), { text: { blocks: { text: 'Something' } } }) + t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something' } } }) undoManager.undo() - t.compare(design.toJSON(), { text: { blocks: { text: 'Type Something' } } }) + t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Type Something' } } }) undoManager.undo() - t.compare(design.toJSON(), { }) + t.compare(design.toJSON().attrs, { }) undoManager.redo() - t.compare(design.toJSON(), { text: { blocks: { text: 'Type Something' } } }) + t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Type Something' } } }) undoManager.redo() - t.compare(design.toJSON(), { text: { blocks: { text: 'Something' } } }) + t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something' } } }) undoManager.redo() - t.compare(design.toJSON(), { text: { blocks: { text: 'Something Else' } } }) + t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something Else' } } }) } /** @@ -505,48 +498,48 @@ export const testUndoNestedUndoIssue = _tc => { */ export const testConsecutiveRedoBug = _tc => { const doc = new Y.Doc() - const yRoot = doc.getMap() + const yRoot = doc.get() const undoMgr = new Y.UndoManager(yRoot) - let yPoint = new Y.Map() - yPoint.set('x', 0) - yPoint.set('y', 0) - yRoot.set('a', yPoint) + let yPoint = new Y.Type() + yPoint.setAttr('x', 0) + yPoint.setAttr('y', 0) + yRoot.setAttr('a', yPoint) undoMgr.stopCapturing() - yPoint.set('x', 100) - yPoint.set('y', 100) + yPoint.setAttr('x', 100) + yPoint.setAttr('y', 100) undoMgr.stopCapturing() - yPoint.set('x', 200) - yPoint.set('y', 200) + yPoint.setAttr('x', 200) + yPoint.setAttr('y', 200) undoMgr.stopCapturing() - yPoint.set('x', 300) - yPoint.set('y', 300) + yPoint.setAttr('x', 300) + yPoint.setAttr('y', 300) undoMgr.stopCapturing() - t.compare(yPoint.toJSON(), { x: 300, y: 300 }) + t.compare(yPoint.toJSON().attrs, { x: 300, y: 300 }) undoMgr.undo() // x=200, y=200 - t.compare(yPoint.toJSON(), { x: 200, y: 200 }) + t.compare(yPoint.toJSON().attrs, { x: 200, y: 200 }) undoMgr.undo() // x=100, y=100 - t.compare(yPoint.toJSON(), { x: 100, y: 100 }) + t.compare(yPoint.toJSON().attrs, { x: 100, y: 100 }) undoMgr.undo() // x=0, y=0 - t.compare(yPoint.toJSON(), { x: 0, y: 0 }) + t.compare(yPoint.toJSON().attrs, { x: 0, y: 0 }) undoMgr.undo() // nil - t.compare(yRoot.get('a'), undefined) + t.compare(yRoot.getAttr('a'), undefined) undoMgr.redo() // x=0, y=0 - yPoint = yRoot.get('a') + yPoint = yRoot.getAttr('a') - t.compare(yPoint.toJSON(), { x: 0, y: 0 }) + t.compare(yPoint.toJSON().attrs, { x: 0, y: 0 }) undoMgr.redo() // x=100, y=100 - t.compare(yPoint.toJSON(), { x: 100, y: 100 }) + t.compare(yPoint.toJSON().attrs, { x: 100, y: 100 }) undoMgr.redo() // x=200, y=200 - t.compare(yPoint.toJSON(), { x: 200, y: 200 }) + t.compare(yPoint.toJSON().attrs, { x: 200, y: 200 }) undoMgr.redo() // expected x=300, y=300, actually nil - t.compare(yPoint.toJSON(), { x: 300, y: 300 }) + t.compare(yPoint.toJSON().attrs, { x: 300, y: 300 }) } /** @@ -557,7 +550,7 @@ export const testConsecutiveRedoBug = _tc => { export const testUndoXmlBug = _tc => { const origin = 'origin' const doc = new Y.Doc() - const fragment = doc.getXmlFragment('t') + const fragment = doc.get('t') const undoManager = new Y.UndoManager(fragment, { captureTimeout: 0, trackedOrigins: new Set([origin]) @@ -565,9 +558,9 @@ export const testUndoXmlBug = _tc => { // create element doc.transact(() => { - const e = new Y.XmlElement('test-node') - e.setAttribute('a', '100') - e.setAttribute('b', '0') + const e = new Y.Type('test-node') + e.setAttr('a', '100') + e.setAttr('b', '0') fragment.insert(fragment.length, [e]) }, origin) @@ -601,44 +594,44 @@ export const testUndoXmlBug = _tc => { */ export const testUndoBlockBug = _tc => { const doc = new Y.Doc({ gc: false }) - const design = doc.getMap() + const design = doc.get() const undoManager = new Y.UndoManager(design, { captureTimeout: 0 }) - const text = new Y.Map() + const text = new Y.Type() - const blocks1 = new Y.Array() - const blocks1block = new Y.Map() + const blocks1 = new Y.Type() + const blocks1block = new Y.Type() doc.transact(() => { - blocks1block.set('text', '1') + blocks1block.setAttr('text', '1') blocks1.push([blocks1block]) - text.set('blocks', blocks1block) - design.set('text', text) + text.setAttr('blocks', blocks1block) + design.setAttr('text', text) }) - const blocks2 = new Y.Array() - const blocks2block = new Y.Map() + const blocks2 = new Y.Type() + const blocks2block = new Y.Type() doc.transact(() => { - blocks2block.set('text', '2') + blocks2block.setAttr('text', '2') blocks2.push([blocks2block]) - text.set('blocks', blocks2block) + text.setAttr('blocks', blocks2block) }) - const blocks3 = new Y.Array() - const blocks3block = new Y.Map() + const blocks3 = new Y.Type() + const blocks3block = new Y.Type() doc.transact(() => { - blocks3block.set('text', '3') + blocks3block.setAttr('text', '3') blocks3.push([blocks3block]) - text.set('blocks', blocks3block) + text.setAttr('blocks', blocks3block) }) - const blocks4 = new Y.Array() - const blocks4block = new Y.Map() + const blocks4 = new Y.Type() + const blocks4block = new Y.Type() doc.transact(() => { - blocks4block.set('text', '4') + blocks4block.setAttr('text', '4') blocks4.push([blocks4block]) - text.set('blocks', blocks4block) + text.setAttr('blocks', blocks4block) }) // {"text":{"blocks":{"text":"4"}}} @@ -650,7 +643,7 @@ export const testUndoBlockBug = _tc => { undoManager.redo() // {"text":{"blocks":{"text":"2"}}} undoManager.redo() // {"text":{"blocks":{"text":"3"}}} undoManager.redo() // {"text":{}} - t.compare(design.toJSON(), { text: { blocks: { text: '4' } } }) + t.compare(design.toJSON().attrs, { text: { blocks: { text: '4' } } }) } /** @@ -661,10 +654,10 @@ export const testUndoBlockBug = _tc => { */ export const testUndoDeleteTextFormat = _tc => { const doc = new Y.Doc() - const text = doc.getText() + const text = doc.get() text.insert(0, 'Attack ships on fire off the shoulder of Orion.') const doc2 = new Y.Doc() - const text2 = doc2.getText() + const text2 = doc2.get() Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc)) const undoManager = new Y.UndoManager(text) @@ -698,16 +691,16 @@ export const testBehaviorOfIgnoreremotemapchangesProperty = _tc => { const doc2 = new Y.Doc() doc.on('update', update => Y.applyUpdate(doc2, update, doc)) doc2.on('update', update => Y.applyUpdate(doc, update, doc2)) - const map1 = doc.getMap() - const map2 = doc2.getMap() + const map1 = doc.get() + const map2 = doc2.get() const um1 = new Y.UndoManager(map1, { ignoreRemoteMapChanges: true }) - map1.set('x', 1) - map2.set('x', 2) - map1.set('x', 3) - map2.set('x', 4) + map1.setAttr('x', 1) + map2.setAttr('x', 2) + map1.setAttr('x', 3) + map2.setAttr('x', 4) um1.undo() - t.assert(map1.get('x') === 2) - t.assert(map2.get('x') === 2) + t.assert(map1.getAttr('x') === 2) + t.assert(map2.getAttr('x') === 2) } /** @@ -719,12 +712,12 @@ export const testBehaviorOfIgnoreremotemapchangesProperty = _tc => { export const testSpecialDeletionCase = _tc => { const origin = 'undoable' const doc = new Y.Doc() - const fragment = doc.getXmlFragment() + const fragment = doc.get() const undoManager = new Y.UndoManager(fragment, { trackedOrigins: new Set([origin]) }) doc.transact(() => { - const e = new Y.XmlElement('test') - e.setAttribute('a', '1') - e.setAttribute('b', '2') + const e = new Y.Type('test') + e.setAttr('a', '1') + e.setAttr('b', '2') fragment.insert(0, [e]) }) t.compareStrings(fragment.toString(), '') @@ -748,26 +741,26 @@ export const testSpecialDeletionCase = _tc => { export const testUndoDeleteInMap = (tc) => { const { map0 } = init(tc, { users: 3 }) const undoManager = new Y.UndoManager(map0, { captureTimeout: 0 }) - map0.set('a', 'a') - map0.delete('a') - map0.set('a', 'b') - map0.delete('a') - map0.set('a', 'c') - map0.delete('a') - map0.set('a', 'd') - t.compare(map0.toJSON(), { a: 'd' }) + map0.setAttr('a', 'a') + map0.deleteAttr('a') + map0.setAttr('a', 'b') + map0.deleteAttr('a') + map0.setAttr('a', 'c') + map0.deleteAttr('a') + map0.setAttr('a', 'd') + t.compare(map0.toJSON().attrs, { a: 'd' }) undoManager.undo() - t.compare(map0.toJSON(), {}) + t.compare(map0.toJSON().attrs, {}) undoManager.undo() - t.compare(map0.toJSON(), { a: 'c' }) + t.compare(map0.toJSON().attrs, { a: 'c' }) undoManager.undo() - t.compare(map0.toJSON(), {}) + t.compare(map0.toJSON().attrs, {}) undoManager.undo() - t.compare(map0.toJSON(), { a: 'b' }) + t.compare(map0.toJSON().attrs, { a: 'b' }) undoManager.undo() - t.compare(map0.toJSON(), {}) + t.compare(map0.toJSON().attrs, {}) undoManager.undo() - t.compare(map0.toJSON(), { a: 'a' }) + t.compare(map0.toJSON().attrs, { a: 'a' }) } /** @@ -777,7 +770,7 @@ export const testUndoDeleteInMap = (tc) => { */ export const testUndoDoingStackItem = async (_tc) => { const doc = new Y.Doc() - const text = doc.getText('text') + const text = doc.get('text') const undoManager = new Y.UndoManager([text]) undoManager.on('stack-item-added', /** @param {any} event */ event => { event.stackItem.meta.set('str', '42') diff --git a/tests/y-text.tests.js b/tests/y-text.tests.js index 250eff12..3607c72c 100644 --- a/tests/y-text.tests.js +++ b/tests/y-text.tests.js @@ -3,7 +3,6 @@ import * as t from 'lib0/testing' import * as prng from 'lib0/prng' import * as math from 'lib0/math' import * as delta from 'lib0/delta' -import * as list from 'lib0/list' import { createIdMapFromIdSet, noAttributionsManager, TwosetAttributionManager, createAttributionManagerFromSnapshots } from 'yjs/internals' const { init, compare } = Y @@ -1215,7 +1214,7 @@ export const testDeltaBug2 = _tc => { }) ytext.applyDelta(changeEvent) const d = ytext.getContent() - t.compare(list.toArray(d.children)[40].toJSON(), { + t.compare(d.toJSON().children?.[40], { type: 'insert', insert: '\n', format: {