From 4b35de5ad518619ae7e2d46b201dbd3cdafa782b Mon Sep 17 00:00:00 2001 From: Will Hawker Date: Tue, 8 Jun 2021 21:09:44 +0100 Subject: [PATCH] add clear to YMap to remove all elements --- README.md | 2 ++ src/types/YMap.js | 16 +++++++++++ tests/y-map.tests.js | 67 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/README.md b/README.md index 5fb44e08..cc1c5136 100644 --- a/README.md +++ b/README.md @@ -334,6 +334,8 @@ or any of its children.
get(index:number)
+ clear() +
Removes all elements from this YMap.
clone():Y.Map
Clone this type into a fresh Yjs type.
toJSON():Object<string, Object|boolean|Array|string|number|Uint8Array> diff --git a/src/types/YMap.js b/src/types/YMap.js index 6cb1b309..351220a2 100644 --- a/src/types/YMap.js +++ b/src/types/YMap.js @@ -237,6 +237,22 @@ export class YMap extends AbstractType { return typeMapHas(this, key) } + /** + * Removes all elements from this YMap. + */ + clear () { + if (this.doc !== null) { + transact(this.doc, transaction => { + this.forEach(function (value, key, map) { + console.log('deleting', key) + typeMapDelete(transaction, map, key) + }) + }) + } else { + /** @type {Map} */ (this._prelimContent).clear() + } + } + /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder */ diff --git a/tests/y-map.tests.js b/tests/y-map.tests.js index 9ac259ab..7cbca52f 100644 --- a/tests/y-map.tests.js +++ b/tests/y-map.tests.js @@ -189,6 +189,49 @@ export const testGetAndSetAndDeleteOfMapProperty = tc => { compare(users) } +/** + * @param {t.TestCase} tc + */ +export const testSetAndClearOfMapProperties = tc => { + const { testConnector, users, map0 } = init(tc, { users: 1 }) + map0.set('stuff', 'c0') + map0.set('otherstuff', 'c1') + map0.clear() + testConnector.flushAllMessages() + for (const user of users) { + const u = user.getMap('map') + t.assert(u.get('stuff') === undefined) + t.assert(u.get('otherstuff') === undefined) + t.assert(u.size === 0, `map size after clear is ${u.size}, expected 0`) + } + compare(users) +} + +/** + * @param {t.TestCase} tc + */ +export const testSetAndClearOfMapPropertiesWithConflicts = tc => { + const { testConnector, users, map0, map1, map2, map3 } = init(tc, { users: 4 }) + map0.set('stuff', 'c0') + map1.set('stuff', 'c1') + map1.set('stuff', 'c2') + map2.set('stuff', 'c3') + testConnector.flushAllMessages() + map0.set('otherstuff', 'c0') + map1.set('otherstuff', 'c1') + map2.set('otherstuff', 'c2') + map3.set('otherstuff', 'c3') + map3.clear() + testConnector.flushAllMessages() + for (const user of users) { + const u = user.getMap('map') + t.assert(u.get('stuff') === undefined) + t.assert(u.get('otherstuff') === undefined) + t.assert(u.size === 0, `map size after clear is ${u.size}, expected 0`) + } + compare(users) +} + /** * @param {t.TestCase} tc */ @@ -335,6 +378,30 @@ export const testThrowsAddAndUpdateAndDeleteEvents = tc => { compare(users) } +/** + * @param {t.TestCase} tc + */ +export const testThrowsDeleteEventsOnClear = tc => { + const { users, map0 } = init(tc, { users: 2 }) + /** + * @type {Object} + */ + let event = {} + map0.observe(e => { + event = e // just put it on event, should be thrown synchronously anyway + }) + // set values + map0.set('stuff', 4) + map0.set('otherstuff', new Y.Array()) + // clear + map0.clear() + compareEvent(event, { + keysChanged: new Set(['stuff', 'otherstuff']), + target: map0 + }) + compare(users) +} + /** * @param {t.TestCase} tc */