Skip to content

Commit a810960

Browse files
committedJan 15, 2023
fix: produce results should never be frozen when returned from nested produces, to prevent 'hiding' drafts. Fixes #935
1 parent 46867f8 commit a810960

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed
 

‎__tests__/regressions.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ function runBaseTest(name, useProxies, autoFreeze, useListener) {
252252
})
253253
})
254254

255-
test("Nested and chained produce calls throw 'Cannot perform 'get' on a proxy that has been revoked' error", () => {
255+
test.only("Nested and chained produce calls throw 'Cannot perform 'get' on a proxy that has been revoked' error", () => {
256256
const state = {
257257
foo: {
258258
bar: {
@@ -267,9 +267,15 @@ function runBaseTest(name, useProxies, autoFreeze, useListener) {
267267
draft.foo = produce(draft.foo, fooDraft => {
268268
/* another produce call makes this fail */
269269
/* no actual mutation necessary to make this happen */
270+
// This happened before becouse the outer object is not modified,
271+
// so assumed to be safely freezable by Immer, while it actually still
272+
// contains a draft of bar, which wasn't retracted since we don't do that in nested
273+
// producers, as it can still be modified outside a produce
270274
})
271275
})
272-
JSON.stringify(newState)
276+
expect(newState).toEqual({
277+
foo: {baz: "apple", bar: {baz: "banana"}}
278+
})
273279
})
274280
})
275281
}

‎src/core/finalize.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ function finalizeProperty(
161161
}
162162

163163
function maybeFreeze(scope: ImmerScope, value: any, deep = false) {
164-
if (scope.immer_.autoFreeze_ && scope.canAutoFreeze_) {
164+
// we never freeze for a non-root scope; as it would prevent pruning for drafts inside wrapping objects
165+
if (!scope.parent_ && scope.immer_.autoFreeze_ && scope.canAutoFreeze_) {
165166
freeze(value, deep)
166167
}
167168
}

‎src/core/immerClass.ts

-2
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ export class Immer implements ProducersFns {
8888
// Only plain objects, arrays, and "immerable classes" are drafted.
8989
if (isDraftable(base)) {
9090
const scope = enterScope(this)
91-
//when base is a draft,can't freeze
92-
scope.canAutoFreeze_ = !isDraft(base)
9391
const proxy = createProxy(this, base, undefined)
9492
let hasError = true
9593
try {

0 commit comments

Comments
 (0)
Please sign in to comment.