From ff25a83820815fd5672a33d4c033f40f3805ed58 Mon Sep 17 00:00:00 2001 From: Andrey Boldyrev Date: Fri, 25 Oct 2019 13:48:02 +0300 Subject: [PATCH] fix specs --- src/common.js | 2 ++ src/patches.js | 17 ++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/common.js b/src/common.js index 6030a935..bf6a00de 100644 --- a/src/common.js +++ b/src/common.js @@ -221,6 +221,8 @@ function latest(state) { export function clone(obj) { if (!isDraftable(obj)) return obj if (Array.isArray(obj)) return obj.map(clone) + if (isMap(obj)) return new Map(obj) + if (isSet(obj)) return new Set(obj) const cloned = Object.create(Object.getPrototypeOf(obj)) for (const key in obj) cloned[key] = clone(obj[key]) return cloned diff --git a/src/patches.js b/src/patches.js index 01ec8b4a..bd2850de 100644 --- a/src/patches.js +++ b/src/patches.js @@ -129,7 +129,6 @@ function generateSetPatches(state, basePath, patches, inversePatches) { export const applyPatches = (draft, patches) => { for (const patch of patches) { const {path, op} = patch - const value = clone(patch.value) // used to clone patch to ensure original patch is not modified, see #411 if (!path.length) throw new Error("Illegal state") @@ -140,21 +139,21 @@ export const applyPatches = (draft, patches) => { throw new Error("Cannot apply patch, path doesn't resolve: " + path.join("/")) // prettier-ignore } + const value = isSet(base) ? patch.value : clone(patch.value) // used to clone patch to ensure original patch is not modified, see #411 + const key = path[path.length - 1] switch (op) { case "replace": if (isMap(base)) { base.set(key, value) - return - } - if (isSet(base)) { + } else if (isSet(base)) { throw new Error('Sets cannot have "replace" patches.') + } else { + // if value is an object, then it's assigned by reference + // in the following add or remove ops, the value field inside the patch will also be modifyed + // so we use value from the cloned patch + base[key] = value } - base[key] = value - // if value is an object, then it's assigned by reference - // in the following add or remove ops, the value field inside the patch will also be modifyed - // so we use value from the cloned patch - base[key] = value break case "add": Array.isArray(base)