From 0f96270840f3b3ab20f566b18a421acdc0eb8d35 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Tue, 11 Jan 2022 11:54:19 +0000 Subject: [PATCH] fix: No patches being generated for root primitive replacements. Fixes #888 --- __tests__/patch.js | 49 ++++++++++++++++++++++++++++++++++++++++++ src/core/finalize.ts | 2 +- src/core/immerClass.ts | 8 ++++++- src/plugins/patches.ts | 4 ++-- src/utils/plugins.ts | 2 +- 5 files changed, 60 insertions(+), 5 deletions(-) diff --git a/__tests__/patch.js b/__tests__/patch.js index 345d75d0..1aa9a533 100644 --- a/__tests__/patch.js +++ b/__tests__/patch.js @@ -1340,3 +1340,52 @@ test("#876 Ensure empty patch set for atomic set+delete on Map", () => { expect(patches).toEqual([]) } }) + +test("#888 patch to a primitive produces the primitive", () => { + { + const [res, patches] = produceWithPatches({abc: 123}, draft => nothing) + expect(res).toEqual(undefined) + expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) + } + { + debugger + const [res, patches] = produceWithPatches(null, draft => nothing) + expect(res).toEqual(undefined) + expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) + } + { + const [res, patches] = produceWithPatches(0, draft => nothing) + expect(res).toEqual(undefined) + expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) + } + { + const [res, patches] = produceWithPatches("foobar", draft => nothing) + expect(res).toEqual(undefined) + expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) + } + { + const [res, patches] = produceWithPatches([], draft => nothing) + expect(res).toEqual(undefined) + expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) + } + { + const [res, patches] = produceWithPatches(false, draft => nothing) + expect(res).toEqual(undefined) + expect(patches).toEqual([{op: "replace", path: [], value: undefined}]) + } + { + const [res, patches] = produceWithPatches( + "foobar", + draft => "something else" + ) + expect(res).toEqual("something else") + expect(patches).toEqual([ + {op: "replace", path: [], value: "something else"} + ]) + } + { + const [res, patches] = produceWithPatches(false, draft => true) + expect(res).toEqual(true) + expect(patches).toEqual([{op: "replace", path: [], value: true}]) + } +}) diff --git a/src/core/finalize.ts b/src/core/finalize.ts index 7c3c404a..ad95b124 100644 --- a/src/core/finalize.ts +++ b/src/core/finalize.ts @@ -37,7 +37,7 @@ export function processResult(result: any, scope: ImmerScope) { } if (scope.patches_) { getPlugin("Patches").generateReplacementPatches_( - baseDraft[DRAFT_STATE], + baseDraft[DRAFT_STATE].base_, result, scope.patches_, scope.inversePatches_! diff --git a/src/core/immerClass.ts b/src/core/immerClass.ts index c8da4023..2a6da927 100644 --- a/src/core/immerClass.ts +++ b/src/core/immerClass.ts @@ -114,9 +114,15 @@ export class Immer implements ProducersFns { return processResult(result, scope) } else if (!base || typeof base !== "object") { result = recipe(base) - if (result === NOTHING) return undefined if (result === undefined) result = base + if (result === NOTHING) result = undefined if (this.autoFreeze_) freeze(result, true) + if (patchListener) { + const p: Patch[] = [] + const ip: Patch[] = [] + getPlugin("Patches").generateReplacementPatches_(base, result, p, ip) + patchListener(p, ip) + } return result } else die(21, base) } diff --git a/src/plugins/patches.ts b/src/plugins/patches.ts index bd3e3d92..08fe9141 100644 --- a/src/plugins/patches.ts +++ b/src/plugins/patches.ts @@ -183,7 +183,7 @@ export function enablePatches() { } function generateReplacementPatches_( - rootState: ImmerState, + baseValue: any, replacement: any, patches: Patch[], inversePatches: Patch[] @@ -196,7 +196,7 @@ export function enablePatches() { inversePatches.push({ op: REPLACE, path: [], - value: rootState.base_ + value: baseValue }) } diff --git a/src/utils/plugins.ts b/src/utils/plugins.ts index 6c959acc..089cf015 100644 --- a/src/utils/plugins.ts +++ b/src/utils/plugins.ts @@ -21,7 +21,7 @@ const plugins: { inversePatches: Patch[] ): void generateReplacementPatches_( - rootState: ImmerState, + base: any, replacement: any, patches: Patch[], inversePatches: Patch[]