From 22e8cd5c15e81f3e9c491d89ce96dfd9aa2efe46 Mon Sep 17 00:00:00 2001 From: Michael Kaeser <87946992+michaelcollabai@users.noreply.github.com> Date: Mon, 16 Jan 2023 12:08:57 +0100 Subject: [PATCH] Fix applying referential equality inside maps and sets (#221) --- src/accessDeep.ts | 24 +++++++++++++++++++++--- src/index.test.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/accessDeep.ts b/src/accessDeep.ts index 8aa5151..989a5cc 100644 --- a/src/accessDeep.ts +++ b/src/accessDeep.ts @@ -26,9 +26,27 @@ function validatePath(path: (string | number)[]) { export const getDeep = (object: object, path: (string | number)[]): object => { validatePath(path); - path.forEach(key => { - object = (object as any)[key]; - }); + for (let i = 0; i < path.length; i++) { + const key = path[i]; + if (isSet(object)) { + object = getNthKey(object, +key); + } else if (isMap(object)) { + const row = +key; + const type = +path[++i] === 0 ? 'key' : 'value'; + + const keyOfRow = getNthKey(object, row); + switch (type) { + case 'key': + object = keyOfRow; + break; + case 'value': + object = object.get(keyOfRow); + break; + } + } else { + object = (object as any)[key]; + } + } return object; }; diff --git a/src/index.test.ts b/src/index.test.ts index 7c90966..14e21e2 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -434,6 +434,39 @@ describe('stringify & parse', () => { }, }, + 'works for referentially equal values in different maps and sets': { + input: () => { + const user = { id: 2 }; + + return { + workspaces: new Map([ + [1, { users: new Set([user]) }], + [2, { users: new Set([user]) }], + ]), + }; + }, + output: { + workspaces: [ + [1, { users: [{ id: 2 }] }], + [2, { users: [{ id: 2 }] }], + ], + }, + outputAnnotations: { + values: { + workspaces: [ + 'map', + { + '0.1.users': ['set'], + '1.1.users': ['set'], + }, + ], + }, + referentialEqualities: { + 'workspaces.0.1.users.0': ['workspaces.1.1.users.0'], + }, + }, + }, + 'works for symbols': { skipOnNode10: true, input: () => {