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
*/