mirror of
https://github.com/yjs/yjs.git
synced 2026-02-23 19:49:59 +01:00
fix all type issues
This commit is contained in:
12
README.md
12
README.md
@@ -231,11 +231,13 @@ document private.
|
||||
</dd>
|
||||
<dt><a href="https://github.com/liveblocks/liveblocks">@liveblocks/yjs </a> 🌟</dt>
|
||||
<dd>
|
||||
<a href="https://liveblocks.io/docs/api-reference/liveblocks-yjs">Liveblocks Yjs</a> 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.
|
||||
<a href="https://liveblocks.io/docs/api-reference/liveblocks-yjs">
|
||||
Liveblocks Yjs
|
||||
</a>
|
||||
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.
|
||||
</dd>
|
||||
<dt><a href="https://github.com/ueberdosis/hocuspocus">Hocuspocus</a> ⭐</dt>
|
||||
<dd>
|
||||
|
||||
65
package-lock.json
generated
65
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<import('../utils/types.js').YType,Array<YEvent<any>>>} StackItemEvent.changedParentTypes
|
||||
* @property {Map<YType,Array<YEvent<any>>>} StackItemEvent.changedParentTypes
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -157,7 +157,7 @@ const popStackItem = (undoManager, stack, eventType) => {
|
||||
*/
|
||||
export class UndoManager extends ObservableV2 {
|
||||
/**
|
||||
* @param {Doc|import('../utils/types.js').YType|Array<import('../utils/types.js').YType>} 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<YType>} 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<import('../utils/types.js').YType | Doc>}
|
||||
* @type {Array<YType | Doc>}
|
||||
*/
|
||||
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> | import('../utils/types.js').YType | Doc} ytypes
|
||||
* @param {Array<YType | Doc> | YType | Doc} ytypes
|
||||
*/
|
||||
addToScope (ytypes) {
|
||||
const tmpSet = new Set(this.scope)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<string,any>}
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -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() === '<undefined><p>content</p></undefined>')
|
||||
// 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<any>}
|
||||
*/
|
||||
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<any>}
|
||||
*/
|
||||
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(), '<test a="1" b="2"></test>')
|
||||
@@ -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')
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user