diff --git a/__tests__/patch.js b/__tests__/patch.js index 8bacae14..7097d545 100644 --- a/__tests__/patch.js +++ b/__tests__/patch.js @@ -720,6 +720,22 @@ describe("arrays - delete", () => { ) }) +describe("arrays - append", () => { + test("appends to array when last part of path is '-'", () => { + const state = { + list: [1, 2, 3] + } + const patch = { + op: "add", + value: 4, + path: ["list", "-"] + } + expect(applyPatches(state, [patch])).toEqual({ + list: [1, 2, 3, 4] + }) + }) +}) + describe("sets - add - 1", () => { runPatchTest( new Set([1]), diff --git a/src/core/immerClass.ts b/src/core/immerClass.ts index 6975225c..074e90f5 100644 --- a/src/core/immerClass.ts +++ b/src/core/immerClass.ts @@ -196,16 +196,21 @@ export class Immer implements ProducersFns { break } } + // If there was a patch that replaced the entire state, start from the + // patch after that. + if (i > -1) { + patches = patches.slice(i + 1) + } const applyPatchesImpl = getPlugin("Patches").applyPatches_ if (isDraft(base)) { // N.B: never hits if some patch a replacement, patches are never drafts - return applyPatchesImpl(base, patches) as any + return applyPatchesImpl(base, patches) } // Otherwise, produce a copy of the base state. return this.produce(base, (draft: Drafted) => - applyPatchesImpl(draft, patches.slice(i + 1)) - ) as any + applyPatchesImpl(draft, patches) + ) } } diff --git a/src/plugins/patches.ts b/src/plugins/patches.ts index c4a7b4ad..bd3e3d92 100644 --- a/src/plugins/patches.ts +++ b/src/plugins/patches.ts @@ -240,7 +240,9 @@ export function enablePatches() { case ADD: switch (type) { case Archtype.Array: - return base.splice(key as any, 0, value) + return key === "-" + ? base.push(value) + : base.splice(key as any, 0, value) case Archtype.Map: return base.set(key, value) case Archtype.Set: