diff --git a/__tests__/07_nested_map_spec.ts b/__tests__/07_nested_map_spec.ts index df7bb92..645cefc 100644 --- a/__tests__/07_nested_map_spec.ts +++ b/__tests__/07_nested_map_spec.ts @@ -147,4 +147,76 @@ describe('issue #14', () => { expect(listener1).toBeCalledTimes(2); expect(listener2).toBeCalledTimes(2); }); + + it('nested map delete', async () => { + type State = Record< + 'items', + { + [key: string]: { + color: string; + }; + } + >; + const doc = new Y.Doc(); + const p = proxy({ + items: { item1: { color: 'blue' }, item2: { color: 'red' } }, + }); + const m = doc.getMap('map') as any; + + bind(p, m); + + delete p.items.item1; + await Promise.resolve(); + + expect(m.get('items').get('item1')).toBeUndefined(); + expect(m.get('items').get('item2')).toBeDefined(); + }); + + it('nested map delete child and parent', async () => { + type State = Record< + 'parents', + { + [key: string]: Record< + 'children', + { + [key: string]: { + color: string; + }; + } + >; + } + >; + const doc = new Y.Doc(); + const p = proxy({ + parents: { + parent1: { + children: { + child1: { color: 'blue' }, + }, + }, + parent2: { + children: { + child2: { color: 'red' }, + }, + }, + }, + }); + const m = doc.getMap('map') as any; + + bind(p, m); + + delete p.parents.parent1.children.child1; + delete p.parents.parent1; + await Promise.resolve(); + + expect(m.toJSON()).toStrictEqual({ + parents: { + parent2: { + children: { + child2: { color: 'red' }, + }, + }, + }, + }); + }); }); diff --git a/src/index.ts b/src/index.ts index 4d2f46d..77c5a09 100644 --- a/src/index.ts +++ b/src/index.ts @@ -73,9 +73,13 @@ const getNestedValues = ( for (let i = 0; i < path.length; i += 1) { const k = path[i]; if (yv instanceof Y.Map) { + // child may already be deleted + if (!pv) break; pv = pv[k]; yv = yv.get(k as string); } else if (yv instanceof Y.Array) { + // child may already be deleted + if (!pv) break; const index = Number(k); pv = pv[k]; yv = yv.get(index);