@vve/immer 8.4.0 → 9.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/immer.js +179 -279
- package/dist/immer.js.map +1 -1
- package/dist/immer.module.js +178 -279
- package/dist/immer.module.js.map +1 -1
- package/dist/immer.umd.js +1 -1
- package/dist/immer.umd.js.map +1 -1
- package/package.json +11 -11
package/dist/immer.module.js
CHANGED
|
@@ -15,16 +15,16 @@ function isDraftable(value) {
|
|
|
15
15
|
function original(value) {
|
|
16
16
|
if (value && value[DRAFT_STATE]) {
|
|
17
17
|
return value[DRAFT_STATE].base;
|
|
18
|
-
}
|
|
19
|
-
|
|
18
|
+
}
|
|
19
|
+
// otherwise return undefined
|
|
20
20
|
}
|
|
21
|
+
|
|
21
22
|
var assign = Object.assign || function assign(target, value) {
|
|
22
23
|
for (var key in value) {
|
|
23
24
|
if (has(value, key)) {
|
|
24
25
|
target[key] = value[key];
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
|
-
|
|
28
28
|
return target;
|
|
29
29
|
};
|
|
30
30
|
var ownKeys = typeof Reflect !== "undefined" && Reflect.ownKeys ? Reflect.ownKeys : typeof Object.getOwnPropertySymbols !== "undefined" ? function (obj) { return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)); } : Object.getOwnPropertyNames;
|
|
@@ -40,15 +40,12 @@ function shallowCopy(base, invokeGetters) {
|
|
|
40
40
|
|
|
41
41
|
var desc = Object.getOwnPropertyDescriptor(base, key);
|
|
42
42
|
var value = desc.value;
|
|
43
|
-
|
|
44
43
|
if (desc.get) {
|
|
45
44
|
if (!invokeGetters) {
|
|
46
45
|
throw new Error("Immer drafts cannot have computed properties");
|
|
47
46
|
}
|
|
48
|
-
|
|
49
47
|
value = desc.get.call(base);
|
|
50
48
|
}
|
|
51
|
-
|
|
52
49
|
if (desc.enumerable) {
|
|
53
50
|
clone[key] = value;
|
|
54
51
|
} else {
|
|
@@ -85,17 +82,17 @@ function is(x, y) {
|
|
|
85
82
|
}
|
|
86
83
|
|
|
87
84
|
/** Each scope represents a `produce` call. */
|
|
88
|
-
|
|
89
85
|
var ImmerScope = function ImmerScope(parent) {
|
|
90
86
|
this.drafts = [];
|
|
91
|
-
this.parent = parent;
|
|
92
|
-
// need to prevent auto-freezing so the unowned draft can be finalized.
|
|
87
|
+
this.parent = parent;
|
|
93
88
|
|
|
94
|
-
|
|
89
|
+
// Whenever the modified draft contains a draft from another scope, we
|
|
90
|
+
// need to prevent auto-freezing so the unowned draft can be finalized.
|
|
91
|
+
this.canAutoFreeze = true;
|
|
95
92
|
|
|
93
|
+
// To avoid prototype lookups:
|
|
96
94
|
this.patches = null;
|
|
97
95
|
};
|
|
98
|
-
|
|
99
96
|
ImmerScope.prototype.usePatches = function usePatches (patchListener) {
|
|
100
97
|
if (patchListener) {
|
|
101
98
|
this.patches = [];
|
|
@@ -103,10 +100,9 @@ ImmerScope.prototype.usePatches = function usePatches (patchListener) {
|
|
|
103
100
|
this.patchListener = patchListener;
|
|
104
101
|
}
|
|
105
102
|
};
|
|
106
|
-
|
|
107
|
-
ImmerScope.prototype.revoke = function revoke$1 (keepAlive) {
|
|
103
|
+
ImmerScope.prototype.revoke = function revoke$1$1 (keepAlive) {
|
|
108
104
|
this.leave();
|
|
109
|
-
keepAlive || this.drafts.forEach(revoke);
|
|
105
|
+
keepAlive || this.drafts.forEach(revoke$1);
|
|
110
106
|
this.drafts = null; // Make draft-related methods throw.
|
|
111
107
|
};
|
|
112
108
|
|
|
@@ -116,43 +112,40 @@ ImmerScope.prototype.leave = function leave () {
|
|
|
116
112
|
}
|
|
117
113
|
};
|
|
118
114
|
ImmerScope.current = null;
|
|
119
|
-
|
|
120
115
|
ImmerScope.enter = function () {
|
|
121
116
|
return this.current = new ImmerScope(this.current);
|
|
122
117
|
};
|
|
123
|
-
|
|
124
|
-
function revoke(draft) {
|
|
118
|
+
function revoke$1(draft) {
|
|
125
119
|
draft[DRAFT_STATE].revoke();
|
|
126
120
|
}
|
|
127
121
|
|
|
122
|
+
// property descriptors are recycled to make sure we don't create a get and set closure per property,
|
|
128
123
|
// but share them all instead
|
|
129
|
-
|
|
130
124
|
var descriptors = {};
|
|
131
|
-
|
|
132
|
-
function willFinalize(scope, result, isReplaced) {
|
|
125
|
+
function willFinalize$1(scope, result, isReplaced) {
|
|
133
126
|
scope.drafts.forEach(function (draft) {
|
|
134
127
|
draft[DRAFT_STATE].finalizing = true;
|
|
135
128
|
});
|
|
136
|
-
|
|
137
129
|
if (!isReplaced) {
|
|
138
130
|
if (scope.patches) {
|
|
139
131
|
markChangesRecursively(scope.drafts[0]);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
}
|
|
133
|
+
// This is faster when we don't care about which attributes changed.
|
|
143
134
|
markChangesSweep(scope.drafts);
|
|
144
|
-
}
|
|
135
|
+
}
|
|
136
|
+
// When a child draft is returned, look for changes.
|
|
145
137
|
else if (isDraft(result) && result[DRAFT_STATE].scope === scope) {
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
markChangesSweep(scope.drafts);
|
|
139
|
+
}
|
|
148
140
|
}
|
|
149
|
-
function createProxy(base, parent) {
|
|
141
|
+
function createProxy$1(base, parent) {
|
|
150
142
|
var isArray = Array.isArray(base);
|
|
151
143
|
var draft = clonePotentialDraft(base);
|
|
152
144
|
each(draft, function (prop) {
|
|
153
145
|
proxyProperty(draft, prop, isArray || isEnumerable(base, prop));
|
|
154
|
-
});
|
|
146
|
+
});
|
|
155
147
|
|
|
148
|
+
// See "proxy.js" for property documentation.
|
|
156
149
|
var scope = parent ? parent.scope : ImmerScope.current;
|
|
157
150
|
var state = {
|
|
158
151
|
scope: scope,
|
|
@@ -165,116 +158,95 @@ function createProxy(base, parent) {
|
|
|
165
158
|
base: base,
|
|
166
159
|
draft: draft,
|
|
167
160
|
copy: null,
|
|
168
|
-
revoke: revoke
|
|
161
|
+
revoke: revoke,
|
|
169
162
|
revoked: false // es5 only
|
|
170
|
-
|
|
171
163
|
};
|
|
164
|
+
|
|
172
165
|
createHiddenProperty(draft, DRAFT_STATE, state);
|
|
173
166
|
scope.drafts.push(draft);
|
|
174
167
|
return draft;
|
|
175
168
|
}
|
|
176
|
-
|
|
177
|
-
function revoke$1() {
|
|
169
|
+
function revoke() {
|
|
178
170
|
this.revoked = true;
|
|
179
171
|
}
|
|
180
|
-
|
|
181
|
-
function source(state) {
|
|
172
|
+
function source$1(state) {
|
|
182
173
|
return state.copy || state.base;
|
|
183
|
-
}
|
|
184
|
-
|
|
174
|
+
}
|
|
185
175
|
|
|
186
|
-
|
|
176
|
+
// Access a property without creating an Immer draft.
|
|
177
|
+
function peek$1(draft, prop) {
|
|
187
178
|
var state = draft[DRAFT_STATE];
|
|
188
|
-
|
|
189
179
|
if (state && !state.finalizing) {
|
|
190
180
|
state.finalizing = true;
|
|
191
181
|
var value = draft[prop];
|
|
192
182
|
state.finalizing = false;
|
|
193
183
|
return value;
|
|
194
184
|
}
|
|
195
|
-
|
|
196
185
|
return draft[prop];
|
|
197
186
|
}
|
|
198
|
-
|
|
199
|
-
function get(state, prop) {
|
|
187
|
+
function get$1(state, prop) {
|
|
200
188
|
assertUnrevoked(state);
|
|
201
|
-
var value = peek(source(state), prop);
|
|
202
|
-
if (state.finalizing) { return value; }
|
|
203
|
-
|
|
204
|
-
if (value === peek(state.base, prop) && isDraftable(value)) {
|
|
189
|
+
var value = peek$1(source$1(state), prop);
|
|
190
|
+
if (state.finalizing) { return value; }
|
|
191
|
+
// Create a draft if the value is unmodified.
|
|
192
|
+
if (value === peek$1(state.base, prop) && isDraftable(value)) {
|
|
205
193
|
prepareCopy(state);
|
|
206
|
-
return state.copy[prop] = createProxy(value, state);
|
|
194
|
+
return state.copy[prop] = createProxy$1(value, state);
|
|
207
195
|
}
|
|
208
|
-
|
|
209
196
|
return value;
|
|
210
197
|
}
|
|
211
|
-
|
|
212
|
-
function set(state, prop, value) {
|
|
198
|
+
function set$1(state, prop, value) {
|
|
213
199
|
assertUnrevoked(state);
|
|
214
200
|
state.assigned[prop] = true;
|
|
215
|
-
|
|
216
201
|
if (!state.modified) {
|
|
217
|
-
if (is(value, peek(source(state), prop))) { return; }
|
|
218
|
-
markChanged(state);
|
|
202
|
+
if (is(value, peek$1(source$1(state), prop))) { return; }
|
|
203
|
+
markChanged$1(state);
|
|
219
204
|
prepareCopy(state);
|
|
220
205
|
}
|
|
221
|
-
|
|
222
206
|
state.copy[prop] = value;
|
|
223
207
|
}
|
|
224
|
-
|
|
225
|
-
function markChanged(state) {
|
|
208
|
+
function markChanged$1(state) {
|
|
226
209
|
if (!state.modified) {
|
|
227
210
|
state.modified = true;
|
|
228
|
-
if (state.parent) { markChanged(state.parent); }
|
|
211
|
+
if (state.parent) { markChanged$1(state.parent); }
|
|
229
212
|
}
|
|
230
213
|
}
|
|
231
|
-
|
|
232
214
|
function prepareCopy(state) {
|
|
233
215
|
if (!state.copy) { state.copy = clonePotentialDraft(state.base); }
|
|
234
216
|
}
|
|
235
|
-
|
|
236
217
|
function clonePotentialDraft(base) {
|
|
237
218
|
var state = base && base[DRAFT_STATE];
|
|
238
|
-
|
|
239
219
|
if (state) {
|
|
240
220
|
state.finalizing = true;
|
|
241
221
|
var draft = shallowCopy(state.draft, true);
|
|
242
222
|
state.finalizing = false;
|
|
243
223
|
return draft;
|
|
244
224
|
}
|
|
245
|
-
|
|
246
225
|
return shallowCopy(base);
|
|
247
226
|
}
|
|
248
|
-
|
|
249
227
|
function proxyProperty(draft, prop, enumerable) {
|
|
250
228
|
var desc = descriptors[prop];
|
|
251
|
-
|
|
252
229
|
if (desc) {
|
|
253
230
|
desc.enumerable = enumerable;
|
|
254
231
|
} else {
|
|
255
232
|
descriptors[prop] = desc = {
|
|
256
233
|
configurable: true,
|
|
257
234
|
enumerable: enumerable,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return get(this[DRAFT_STATE], prop);
|
|
235
|
+
get: function get$1$1() {
|
|
236
|
+
return get$1(this[DRAFT_STATE], prop);
|
|
261
237
|
},
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
set(this[DRAFT_STATE], prop, value);
|
|
238
|
+
set: function set$1$1(value) {
|
|
239
|
+
set$1(this[DRAFT_STATE], prop, value);
|
|
265
240
|
}
|
|
266
|
-
|
|
267
241
|
};
|
|
268
242
|
}
|
|
269
|
-
|
|
270
243
|
Object.defineProperty(draft, prop, desc);
|
|
271
244
|
}
|
|
272
|
-
|
|
273
245
|
function assertUnrevoked(state) {
|
|
274
|
-
if (state.revoked === true) { throw new Error("Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + JSON.stringify(source(state))); }
|
|
275
|
-
}
|
|
276
|
-
|
|
246
|
+
if (state.revoked === true) { throw new Error("Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + JSON.stringify(source$1(state))); }
|
|
247
|
+
}
|
|
277
248
|
|
|
249
|
+
// This looks expensive, but only proxies are visited, and only objects without known changes are scanned.
|
|
278
250
|
function markChangesSweep(drafts) {
|
|
279
251
|
// The natural order of drafts in the `scope` array is based on when they
|
|
280
252
|
// were accessed. By processing drafts in reverse natural order, we have a
|
|
@@ -282,15 +254,13 @@ function markChangesSweep(drafts) {
|
|
|
282
254
|
// have changed, we can avoid any traversal of its ancestor nodes.
|
|
283
255
|
for (var i = drafts.length - 1; i >= 0; i--) {
|
|
284
256
|
var state = drafts[i][DRAFT_STATE];
|
|
285
|
-
|
|
286
257
|
if (!state.modified) {
|
|
287
258
|
if (Array.isArray(state.base)) {
|
|
288
|
-
if (hasArrayChanges(state)) { markChanged(state); }
|
|
289
|
-
} else if (hasObjectChanges(state)) { markChanged(state); }
|
|
259
|
+
if (hasArrayChanges(state)) { markChanged$1(state); }
|
|
260
|
+
} else if (hasObjectChanges(state)) { markChanged$1(state); }
|
|
290
261
|
}
|
|
291
262
|
}
|
|
292
263
|
}
|
|
293
|
-
|
|
294
264
|
function markChangesRecursively(object) {
|
|
295
265
|
if (!object || typeof object !== "object") { return; }
|
|
296
266
|
var state = object[DRAFT_STATE];
|
|
@@ -298,91 +268,85 @@ function markChangesRecursively(object) {
|
|
|
298
268
|
var base = state.base;
|
|
299
269
|
var draft = state.draft;
|
|
300
270
|
var assigned = state.assigned;
|
|
301
|
-
|
|
302
271
|
if (!Array.isArray(object)) {
|
|
303
272
|
// Look for added keys.
|
|
304
273
|
Object.keys(draft).forEach(function (key) {
|
|
305
274
|
// The `undefined` check is a fast path for pre-existing keys.
|
|
306
275
|
if (base[key] === undefined && !has(base, key)) {
|
|
307
276
|
assigned[key] = true;
|
|
308
|
-
markChanged(state);
|
|
277
|
+
markChanged$1(state);
|
|
309
278
|
} else if (!assigned[key]) {
|
|
310
279
|
// Only untouched properties trigger recursion.
|
|
311
280
|
markChangesRecursively(draft[key]);
|
|
312
281
|
}
|
|
313
|
-
});
|
|
314
|
-
|
|
282
|
+
});
|
|
283
|
+
// Look for removed keys.
|
|
315
284
|
Object.keys(base).forEach(function (key) {
|
|
316
285
|
// The `undefined` check is a fast path for pre-existing keys.
|
|
317
286
|
if (draft[key] === undefined && !has(draft, key)) {
|
|
318
287
|
assigned[key] = false;
|
|
319
|
-
markChanged(state);
|
|
288
|
+
markChanged$1(state);
|
|
320
289
|
}
|
|
321
290
|
});
|
|
322
291
|
} else if (hasArrayChanges(state)) {
|
|
323
|
-
markChanged(state);
|
|
292
|
+
markChanged$1(state);
|
|
324
293
|
assigned.length = true;
|
|
325
|
-
|
|
326
294
|
if (draft.length < base.length) {
|
|
327
295
|
for (var i = draft.length; i < base.length; i++) { assigned[i] = false; }
|
|
328
296
|
} else {
|
|
329
297
|
for (var i$1 = base.length; i$1 < draft.length; i$1++) { assigned[i$1] = true; }
|
|
330
298
|
}
|
|
331
|
-
|
|
332
299
|
for (var i$2 = 0; i$2 < draft.length; i$2++) {
|
|
333
300
|
// Only untouched indices trigger recursion.
|
|
334
301
|
if (assigned[i$2] === undefined) { markChangesRecursively(draft[i$2]); }
|
|
335
302
|
}
|
|
336
303
|
}
|
|
337
304
|
}
|
|
338
|
-
|
|
339
305
|
function hasObjectChanges(state) {
|
|
340
306
|
var base = state.base;
|
|
341
|
-
var draft = state.draft;
|
|
342
|
-
// non-numeric keys are ordered by time of definition on the object.
|
|
307
|
+
var draft = state.draft;
|
|
343
308
|
|
|
309
|
+
// Search for added keys and changed keys. Start at the back, because
|
|
310
|
+
// non-numeric keys are ordered by time of definition on the object.
|
|
344
311
|
var keys = Object.keys(draft);
|
|
345
|
-
|
|
346
312
|
for (var i = keys.length - 1; i >= 0; i--) {
|
|
347
313
|
var key = keys[i];
|
|
348
|
-
var baseValue = base[key];
|
|
349
|
-
|
|
314
|
+
var baseValue = base[key];
|
|
315
|
+
// The `undefined` check is a fast path for pre-existing keys.
|
|
350
316
|
if (baseValue === undefined && !has(base, key)) {
|
|
351
317
|
return true;
|
|
352
|
-
}
|
|
318
|
+
}
|
|
319
|
+
// Once a base key is deleted, future changes go undetected, because its
|
|
353
320
|
// descriptor is erased. This branch detects any missed changes.
|
|
354
321
|
else {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
return true;
|
|
360
|
-
}
|
|
322
|
+
var value = draft[key];
|
|
323
|
+
var state$1 = value && value[DRAFT_STATE];
|
|
324
|
+
if (state$1 ? state$1.base !== baseValue : !is(value, baseValue)) {
|
|
325
|
+
return true;
|
|
361
326
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
327
|
+
}
|
|
328
|
+
}
|
|
365
329
|
|
|
330
|
+
// At this point, no keys were added or changed.
|
|
331
|
+
// Compare key count to determine if keys were deleted.
|
|
366
332
|
return keys.length !== Object.keys(base).length;
|
|
367
333
|
}
|
|
368
|
-
|
|
369
334
|
function hasArrayChanges(state) {
|
|
370
335
|
var draft = state.draft;
|
|
371
|
-
if (draft.length !== state.base.length) { return true; }
|
|
336
|
+
if (draft.length !== state.base.length) { return true; }
|
|
337
|
+
// See #116
|
|
372
338
|
// If we first shorten the length, our array interceptors will be removed.
|
|
373
339
|
// If after that new items are added, result in the same original length,
|
|
374
340
|
// those last items will have no intercepting property.
|
|
375
341
|
// So if there is no own descriptor on the last position, we know that items were removed and added
|
|
376
342
|
// N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check
|
|
377
343
|
// the last one
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
344
|
+
var descriptor = Object.getOwnPropertyDescriptor(draft, draft.length - 1);
|
|
345
|
+
// descriptor can be null, but only for newly created sparse arrays, eg. new Array(10)
|
|
346
|
+
if (descriptor && !descriptor.get) { return true; }
|
|
347
|
+
// For all other cases, we don't have to compare, as they would have been picked up by the index setters
|
|
383
348
|
return false;
|
|
384
349
|
}
|
|
385
|
-
|
|
386
350
|
function createHiddenProperty(target, prop, value) {
|
|
387
351
|
Object.defineProperty(target, prop, {
|
|
388
352
|
value: value,
|
|
@@ -393,12 +357,13 @@ function createHiddenProperty(target, prop, value) {
|
|
|
393
357
|
|
|
394
358
|
var legacyProxy = /*#__PURE__*/Object.freeze({
|
|
395
359
|
__proto__: null,
|
|
396
|
-
willFinalize: willFinalize,
|
|
397
|
-
createProxy: createProxy
|
|
360
|
+
willFinalize: willFinalize$1,
|
|
361
|
+
createProxy: createProxy$1
|
|
398
362
|
});
|
|
399
363
|
|
|
400
|
-
|
|
401
|
-
function
|
|
364
|
+
// Do nothing before being finalized.
|
|
365
|
+
function willFinalize() {}
|
|
366
|
+
function createProxy(base, parent) {
|
|
402
367
|
var scope = parent ? parent.scope : ImmerScope.current;
|
|
403
368
|
var state = {
|
|
404
369
|
// Track which produce call this is associated with.
|
|
@@ -422,7 +387,8 @@ function createProxy$1(base, parent) {
|
|
|
422
387
|
// Called by the `produce` function.
|
|
423
388
|
revoke: null
|
|
424
389
|
};
|
|
425
|
-
var ref = Array.isArray(base) ?
|
|
390
|
+
var ref = Array.isArray(base) ?
|
|
391
|
+
// [state] is used for arrays, to make sure the proxy is array-ish and not violate invariants,
|
|
426
392
|
// although state itself is an object
|
|
427
393
|
Proxy.revocable([state], arrayTraps) : Proxy.revocable(state, objectTraps);
|
|
428
394
|
var revoke = ref.revoke;
|
|
@@ -433,20 +399,16 @@ function createProxy$1(base, parent) {
|
|
|
433
399
|
return proxy;
|
|
434
400
|
}
|
|
435
401
|
var objectTraps = {
|
|
436
|
-
get: get
|
|
437
|
-
|
|
402
|
+
get: get,
|
|
438
403
|
has: function has(target, prop) {
|
|
439
|
-
return prop in source
|
|
404
|
+
return prop in source(target);
|
|
440
405
|
},
|
|
441
|
-
|
|
442
406
|
ownKeys: function ownKeys(target) {
|
|
443
|
-
return Reflect.ownKeys(source
|
|
407
|
+
return Reflect.ownKeys(source(target));
|
|
444
408
|
},
|
|
445
|
-
|
|
446
|
-
set: set$1,
|
|
409
|
+
set: set,
|
|
447
410
|
deleteProperty: deleteProperty,
|
|
448
411
|
getOwnPropertyDescriptor: getOwnPropertyDescriptor,
|
|
449
|
-
|
|
450
412
|
defineProperty: function defineProperty() {
|
|
451
413
|
throw new Error("Object.defineProperty() cannot be used on an Immer draft"); // prettier-ignore
|
|
452
414
|
},
|
|
@@ -454,12 +416,11 @@ var objectTraps = {
|
|
|
454
416
|
getPrototypeOf: function getPrototypeOf(target) {
|
|
455
417
|
return Object.getPrototypeOf(target.base);
|
|
456
418
|
},
|
|
457
|
-
|
|
458
419
|
setPrototypeOf: function setPrototypeOf() {
|
|
459
420
|
throw new Error("Object.setPrototypeOf() cannot be used on an Immer draft"); // prettier-ignore
|
|
460
421
|
}
|
|
461
|
-
|
|
462
422
|
};
|
|
423
|
+
|
|
463
424
|
var arrayTraps = {};
|
|
464
425
|
each(objectTraps, function (key, fn) {
|
|
465
426
|
arrayTraps[key] = function () {
|
|
@@ -467,7 +428,6 @@ each(objectTraps, function (key, fn) {
|
|
|
467
428
|
return fn.apply(this, arguments);
|
|
468
429
|
};
|
|
469
430
|
});
|
|
470
|
-
|
|
471
431
|
arrayTraps.deleteProperty = function (state, prop) {
|
|
472
432
|
if (isNaN(parseInt(prop))) {
|
|
473
433
|
throw new Error("Immer only supports deleting array indices"); // prettier-ignore
|
|
@@ -475,140 +435,127 @@ arrayTraps.deleteProperty = function (state, prop) {
|
|
|
475
435
|
|
|
476
436
|
return objectTraps.deleteProperty.call(this, state[0], prop);
|
|
477
437
|
};
|
|
478
|
-
|
|
479
438
|
arrayTraps.set = function (state, prop, value) {
|
|
480
439
|
if (prop !== "length" && isNaN(parseInt(prop))) {
|
|
481
440
|
throw new Error("Immer only supports setting array indices and the 'length' property"); // prettier-ignore
|
|
482
441
|
}
|
|
483
442
|
|
|
484
443
|
return objectTraps.set.call(this, state[0], prop, value);
|
|
485
|
-
};
|
|
486
|
-
|
|
444
|
+
};
|
|
487
445
|
|
|
488
|
-
|
|
446
|
+
// returns the object we should be reading the current value from, which is base, until some change has been made
|
|
447
|
+
function source(state) {
|
|
489
448
|
return state.copy || state.base;
|
|
490
|
-
}
|
|
491
|
-
|
|
449
|
+
}
|
|
492
450
|
|
|
493
|
-
|
|
451
|
+
// Access a property without creating an Immer draft.
|
|
452
|
+
function peek(draft, prop) {
|
|
494
453
|
var state = draft[DRAFT_STATE];
|
|
495
|
-
var desc = Reflect.getOwnPropertyDescriptor(state ? source
|
|
454
|
+
var desc = Reflect.getOwnPropertyDescriptor(state ? source(state) : draft, prop);
|
|
496
455
|
return desc && desc.value;
|
|
497
456
|
}
|
|
498
|
-
|
|
499
|
-
function get$1(state, prop) {
|
|
457
|
+
function get(state, prop) {
|
|
500
458
|
if (prop === DRAFT_STATE) { return state; }
|
|
501
|
-
var drafts = state.drafts;
|
|
459
|
+
var drafts = state.drafts;
|
|
502
460
|
|
|
461
|
+
// Check for existing draft in unmodified state.
|
|
503
462
|
if (!state.modified && has(drafts, prop)) {
|
|
504
463
|
return drafts[prop];
|
|
505
464
|
}
|
|
506
|
-
|
|
507
|
-
var value = source$1(state)[prop];
|
|
508
|
-
|
|
465
|
+
var value = source(state)[prop];
|
|
509
466
|
if (state.finalized || !isDraftable(value)) {
|
|
510
467
|
return value;
|
|
511
|
-
}
|
|
512
|
-
|
|
468
|
+
}
|
|
513
469
|
|
|
470
|
+
// Check for existing draft in modified state.
|
|
514
471
|
if (state.modified) {
|
|
515
472
|
// Assigned values are never drafted. This catches any drafts we created, too.
|
|
516
|
-
if (value !== peek
|
|
517
|
-
|
|
473
|
+
if (value !== peek(state.base, prop)) { return value; }
|
|
474
|
+
// Store drafts on the copy (when one exists).
|
|
518
475
|
drafts = state.copy;
|
|
519
476
|
}
|
|
520
|
-
|
|
521
|
-
return drafts[prop] = createProxy$1(value, state);
|
|
477
|
+
return drafts[prop] = createProxy(value, state);
|
|
522
478
|
}
|
|
523
|
-
|
|
524
|
-
function set$1(state, prop, value) {
|
|
479
|
+
function set(state, prop, value) {
|
|
525
480
|
if (!state.modified) {
|
|
526
|
-
var baseValue = peek
|
|
481
|
+
var baseValue = peek(state.base, prop);
|
|
482
|
+
// Optimize based on value's truthiness. Truthy values are guaranteed to
|
|
527
483
|
// never be undefined, so we can avoid the `in` operator. Lastly, truthy
|
|
528
484
|
// values may be drafts, but falsy values are never drafts.
|
|
529
|
-
|
|
530
485
|
var isUnchanged = value ? is(baseValue, value) || value === state.drafts[prop] : is(baseValue, value) && prop in state.base;
|
|
531
486
|
if (isUnchanged) { return true; }
|
|
532
|
-
markChanged
|
|
487
|
+
markChanged(state);
|
|
533
488
|
}
|
|
534
|
-
|
|
535
489
|
state.assigned[prop] = true;
|
|
536
490
|
state.copy[prop] = value;
|
|
537
491
|
return true;
|
|
538
492
|
}
|
|
539
|
-
|
|
540
493
|
function deleteProperty(state, prop) {
|
|
541
494
|
// The `undefined` check is a fast path for pre-existing keys.
|
|
542
|
-
if (peek
|
|
495
|
+
if (peek(state.base, prop) !== undefined || prop in state.base) {
|
|
543
496
|
state.assigned[prop] = false;
|
|
544
|
-
markChanged
|
|
497
|
+
markChanged(state);
|
|
545
498
|
}
|
|
546
|
-
|
|
547
499
|
if (state.copy) { delete state.copy[prop]; }
|
|
548
500
|
return true;
|
|
549
|
-
}
|
|
550
|
-
// the same guarantee in ES5 mode.
|
|
551
|
-
|
|
501
|
+
}
|
|
552
502
|
|
|
503
|
+
// Note: We never coerce `desc.value` into an Immer draft, because we can't make
|
|
504
|
+
// the same guarantee in ES5 mode.
|
|
553
505
|
function getOwnPropertyDescriptor(state, prop) {
|
|
554
|
-
var owner = source
|
|
506
|
+
var owner = source(state);
|
|
555
507
|
var desc = Reflect.getOwnPropertyDescriptor(owner, prop);
|
|
556
|
-
|
|
557
508
|
if (desc) {
|
|
558
509
|
desc.writable = true;
|
|
559
510
|
desc.configurable = !Array.isArray(owner) || prop !== "length";
|
|
560
511
|
}
|
|
561
|
-
|
|
562
512
|
return desc;
|
|
563
513
|
}
|
|
564
|
-
|
|
565
|
-
function markChanged$1(state) {
|
|
514
|
+
function markChanged(state) {
|
|
566
515
|
if (!state.modified) {
|
|
567
516
|
state.modified = true;
|
|
568
517
|
state.copy = assign(shallowCopy(state.base), state.drafts);
|
|
569
518
|
state.drafts = null;
|
|
570
|
-
if (state.parent) { markChanged
|
|
519
|
+
if (state.parent) { markChanged(state.parent); }
|
|
571
520
|
}
|
|
572
521
|
}
|
|
573
522
|
|
|
574
523
|
var modernProxy = /*#__PURE__*/Object.freeze({
|
|
575
524
|
__proto__: null,
|
|
576
|
-
willFinalize: willFinalize
|
|
577
|
-
createProxy: createProxy
|
|
525
|
+
willFinalize: willFinalize,
|
|
526
|
+
createProxy: createProxy
|
|
578
527
|
});
|
|
579
528
|
|
|
580
529
|
function generatePatches(state, basePath, patches, inversePatches) {
|
|
581
530
|
Array.isArray(state.base) ? generateArrayPatches(state, basePath, patches, inversePatches) : generateObjectPatches(state, basePath, patches, inversePatches);
|
|
582
531
|
}
|
|
583
|
-
|
|
584
532
|
function generateArrayPatches(state, basePath, patches, inversePatches) {
|
|
585
533
|
var assign, assign$1;
|
|
586
534
|
|
|
587
535
|
var base = state.base;
|
|
588
536
|
var copy = state.copy;
|
|
589
|
-
var assigned = state.assigned;
|
|
537
|
+
var assigned = state.assigned;
|
|
590
538
|
|
|
539
|
+
// Reduce complexity by ensuring `base` is never longer.
|
|
591
540
|
if (copy.length < base.length) {
|
|
592
541
|
(assign = [copy, base], base = assign[0], copy = assign[1]);
|
|
593
542
|
(assign$1 = [inversePatches, patches], patches = assign$1[0], inversePatches = assign$1[1]);
|
|
594
543
|
}
|
|
544
|
+
var delta = copy.length - base.length;
|
|
595
545
|
|
|
596
|
-
|
|
597
|
-
|
|
546
|
+
// Find the first replaced index.
|
|
598
547
|
var start = 0;
|
|
599
|
-
|
|
600
548
|
while (base[start] === copy[start] && start < base.length) {
|
|
601
549
|
++start;
|
|
602
|
-
}
|
|
603
|
-
|
|
550
|
+
}
|
|
604
551
|
|
|
552
|
+
// Find the last replaced index. Search from the end to optimize splice patches.
|
|
605
553
|
var end = base.length;
|
|
606
|
-
|
|
607
554
|
while (end > start && base[end - 1] === copy[end + delta - 1]) {
|
|
608
555
|
--end;
|
|
609
|
-
}
|
|
610
|
-
|
|
556
|
+
}
|
|
611
557
|
|
|
558
|
+
// Process replaced indices.
|
|
612
559
|
for (var i = start; i < end; ++i) {
|
|
613
560
|
if (assigned[i] && copy[i] !== base[i]) {
|
|
614
561
|
var path = basePath.concat([i]);
|
|
@@ -624,10 +571,10 @@ function generateArrayPatches(state, basePath, patches, inversePatches) {
|
|
|
624
571
|
});
|
|
625
572
|
}
|
|
626
573
|
}
|
|
627
|
-
|
|
628
574
|
var useRemove = end != base.length;
|
|
629
|
-
var replaceCount = patches.length;
|
|
575
|
+
var replaceCount = patches.length;
|
|
630
576
|
|
|
577
|
+
// Process added indices.
|
|
631
578
|
for (var i$1 = end + delta - 1; i$1 >= end; --i$1) {
|
|
632
579
|
var path$1 = basePath.concat([i$1]);
|
|
633
580
|
patches[replaceCount + i$1 - end] = {
|
|
@@ -635,16 +582,15 @@ function generateArrayPatches(state, basePath, patches, inversePatches) {
|
|
|
635
582
|
path: path$1,
|
|
636
583
|
value: copy[i$1]
|
|
637
584
|
};
|
|
638
|
-
|
|
639
585
|
if (useRemove) {
|
|
640
586
|
inversePatches.push({
|
|
641
587
|
op: "remove",
|
|
642
588
|
path: path$1
|
|
643
589
|
});
|
|
644
590
|
}
|
|
645
|
-
}
|
|
646
|
-
|
|
591
|
+
}
|
|
647
592
|
|
|
593
|
+
// One "replace" patch reverses all non-splicing "add" patches.
|
|
648
594
|
if (!useRemove) {
|
|
649
595
|
inversePatches.push({
|
|
650
596
|
op: "replace",
|
|
@@ -653,7 +599,6 @@ function generateArrayPatches(state, basePath, patches, inversePatches) {
|
|
|
653
599
|
});
|
|
654
600
|
}
|
|
655
601
|
}
|
|
656
|
-
|
|
657
602
|
function generateObjectPatches(state, basePath, patches, inversePatches) {
|
|
658
603
|
var base = state.base;
|
|
659
604
|
var copy = state.copy;
|
|
@@ -685,29 +630,24 @@ function generateObjectPatches(state, basePath, patches, inversePatches) {
|
|
|
685
630
|
});
|
|
686
631
|
});
|
|
687
632
|
}
|
|
688
|
-
|
|
689
|
-
function applyPatches(draft, patches) {
|
|
633
|
+
function applyPatches$1(draft, patches) {
|
|
690
634
|
for (var i = 0; i < patches.length; i++) {
|
|
691
635
|
var patch = patches[i];
|
|
692
636
|
var path = patch.path;
|
|
693
|
-
|
|
694
637
|
if (path.length === 0 && patch.op === "replace") {
|
|
695
638
|
draft = patch.value;
|
|
696
639
|
} else {
|
|
697
640
|
var base = draft;
|
|
698
|
-
|
|
699
641
|
for (var i$1 = 0; i$1 < path.length - 1; i$1++) {
|
|
700
642
|
base = base[path[i$1]];
|
|
701
643
|
if (!base || typeof base !== "object") { throw new Error("Cannot apply patch, path doesn't resolve: " + path.join("/")); } // prettier-ignore
|
|
702
644
|
}
|
|
703
645
|
|
|
704
646
|
var key = path[path.length - 1];
|
|
705
|
-
|
|
706
647
|
switch (patch.op) {
|
|
707
648
|
case "replace":
|
|
708
649
|
base[key] = patch.value;
|
|
709
650
|
break;
|
|
710
|
-
|
|
711
651
|
case "add":
|
|
712
652
|
if (Array.isArray(base)) {
|
|
713
653
|
// TODO: support "foo/-" paths for appending to an array
|
|
@@ -715,29 +655,23 @@ function applyPatches(draft, patches) {
|
|
|
715
655
|
} else {
|
|
716
656
|
base[key] = patch.value;
|
|
717
657
|
}
|
|
718
|
-
|
|
719
658
|
break;
|
|
720
|
-
|
|
721
659
|
case "remove":
|
|
722
660
|
if (Array.isArray(base)) {
|
|
723
661
|
base.splice(key, 1);
|
|
724
662
|
} else {
|
|
725
663
|
delete base[key];
|
|
726
664
|
}
|
|
727
|
-
|
|
728
665
|
break;
|
|
729
|
-
|
|
730
666
|
default:
|
|
731
667
|
throw new Error("Unsupported patch operation: " + patch.op);
|
|
732
668
|
}
|
|
733
669
|
}
|
|
734
670
|
}
|
|
735
|
-
|
|
736
671
|
return draft;
|
|
737
672
|
}
|
|
738
673
|
|
|
739
674
|
function verifyMinified() {}
|
|
740
|
-
|
|
741
675
|
var configDefaults = {
|
|
742
676
|
useProxies: typeof Proxy !== "undefined" && typeof Reflect !== "undefined",
|
|
743
677
|
autoFreeze: typeof process !== "undefined" ? process.env.NODE_ENV !== "production" : verifyMinified.name === "verifyMinified",
|
|
@@ -750,9 +684,8 @@ var Immer = function Immer(config) {
|
|
|
750
684
|
this.setUseProxies(this.useProxies);
|
|
751
685
|
this.produce = this.produce.bind(this);
|
|
752
686
|
};
|
|
753
|
-
|
|
754
687
|
Immer.prototype.produce = function produce (base, recipe, patchListener) {
|
|
755
|
-
var this$1 = this;
|
|
688
|
+
var this$1$1 = this;
|
|
756
689
|
|
|
757
690
|
// curried invocation
|
|
758
691
|
if (typeof base === "function" && typeof recipe !== "function") {
|
|
@@ -760,32 +693,31 @@ Immer.prototype.produce = function produce (base, recipe, patchListener) {
|
|
|
760
693
|
recipe = base;
|
|
761
694
|
var self = this;
|
|
762
695
|
return function curriedProduce(base) {
|
|
763
|
-
var this$1 = this;
|
|
696
|
+
var this$1$1 = this;
|
|
764
697
|
if ( base === void 0 ) base = defaultBase;
|
|
765
698
|
var args = [], len = arguments.length - 1;
|
|
766
699
|
while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
|
|
767
700
|
|
|
768
|
-
return self.produce(base, function (draft) { return recipe.call.apply(recipe, [ this$1, draft ].concat( args )); }); // prettier-ignore
|
|
701
|
+
return self.produce(base, function (draft) { return recipe.call.apply(recipe, [ this$1$1, draft ].concat( args )); }); // prettier-ignore
|
|
769
702
|
};
|
|
770
|
-
}
|
|
771
|
-
|
|
703
|
+
}
|
|
772
704
|
|
|
705
|
+
// prettier-ignore
|
|
773
706
|
{
|
|
774
707
|
if (typeof recipe !== "function") {
|
|
775
708
|
throw new Error("The first or second argument to `produce` must be a function");
|
|
776
709
|
}
|
|
777
|
-
|
|
778
710
|
if (patchListener !== undefined && typeof patchListener !== "function") {
|
|
779
711
|
throw new Error("The third argument to `produce` must be a function or undefined");
|
|
780
712
|
}
|
|
781
713
|
}
|
|
782
|
-
var result;
|
|
714
|
+
var result;
|
|
783
715
|
|
|
716
|
+
// Only plain objects, arrays, and "immerable classes" are drafted.
|
|
784
717
|
if (isDraftable(base)) {
|
|
785
718
|
var scope = ImmerScope.enter();
|
|
786
719
|
var proxy = this.createProxy(base);
|
|
787
720
|
var hasError = true;
|
|
788
|
-
|
|
789
721
|
try {
|
|
790
722
|
result = recipe(proxy);
|
|
791
723
|
hasError = false;
|
|
@@ -793,17 +725,15 @@ Immer.prototype.produce = function produce (base, recipe, patchListener) {
|
|
|
793
725
|
// finally instead of catch + rethrow better preserves original stack
|
|
794
726
|
if (hasError) { scope.revoke(); }else { scope.leave(); }
|
|
795
727
|
}
|
|
796
|
-
|
|
797
728
|
if (result instanceof Promise) {
|
|
798
729
|
return result.then(function (result) {
|
|
799
730
|
scope.usePatches(patchListener);
|
|
800
|
-
return this$1.processResult(result, scope);
|
|
731
|
+
return this$1$1.processResult(result, scope);
|
|
801
732
|
}, function (error) {
|
|
802
733
|
scope.revoke();
|
|
803
734
|
throw error;
|
|
804
735
|
});
|
|
805
736
|
}
|
|
806
|
-
|
|
807
737
|
scope.usePatches(patchListener);
|
|
808
738
|
return this.processResult(result, scope);
|
|
809
739
|
} else {
|
|
@@ -812,7 +742,6 @@ Immer.prototype.produce = function produce (base, recipe, patchListener) {
|
|
|
812
742
|
return result !== NOTHING ? result : undefined;
|
|
813
743
|
}
|
|
814
744
|
};
|
|
815
|
-
|
|
816
745
|
Immer.prototype.createDraft = function createDraft (base) {
|
|
817
746
|
if (!isDraftable(base)) {
|
|
818
747
|
throw new Error("First argument to `createDraft` must be a plain object, an array, or an immerable object"); // prettier-ignore
|
|
@@ -824,10 +753,8 @@ Immer.prototype.createDraft = function createDraft (base) {
|
|
|
824
753
|
scope.leave();
|
|
825
754
|
return proxy;
|
|
826
755
|
};
|
|
827
|
-
|
|
828
756
|
Immer.prototype.finishDraft = function finishDraft (draft, patchListener, keepAlive) {
|
|
829
757
|
var state = draft && draft[DRAFT_STATE];
|
|
830
|
-
|
|
831
758
|
if (!state || !state.isManual) {
|
|
832
759
|
throw new Error("First argument to `finishDraft` must be a draft returned by `createDraft`"); // prettier-ignore
|
|
833
760
|
}
|
|
@@ -840,33 +767,26 @@ Immer.prototype.finishDraft = function finishDraft (draft, patchListener, keepAl
|
|
|
840
767
|
scope.usePatches(patchListener);
|
|
841
768
|
return this.processResult(undefined, scope, keepAlive);
|
|
842
769
|
};
|
|
843
|
-
|
|
844
770
|
Immer.prototype.setAutoFreeze = function setAutoFreeze (value) {
|
|
845
771
|
this.autoFreeze = value;
|
|
846
772
|
};
|
|
847
|
-
|
|
848
773
|
Immer.prototype.setUseProxies = function setUseProxies (value) {
|
|
849
774
|
this.useProxies = value;
|
|
850
775
|
assign(this, value ? modernProxy : legacyProxy);
|
|
851
776
|
};
|
|
852
|
-
|
|
853
|
-
Immer.prototype.applyPatches = function applyPatches$1 (base, patches) {
|
|
777
|
+
Immer.prototype.applyPatches = function applyPatches$1$1 (base, patches) {
|
|
854
778
|
// Mutate the base state when a draft is passed.
|
|
855
779
|
if (isDraft(base)) {
|
|
856
|
-
return applyPatches(base, patches);
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
return this.produce(base, function (draft) { return applyPatches(draft, patches); });
|
|
780
|
+
return applyPatches$1(base, patches);
|
|
781
|
+
}
|
|
782
|
+
// Otherwise, produce a copy of the base state.
|
|
783
|
+
return this.produce(base, function (draft) { return applyPatches$1(draft, patches); });
|
|
861
784
|
};
|
|
862
785
|
/** @internal */
|
|
863
|
-
|
|
864
|
-
|
|
865
786
|
Immer.prototype.processResult = function processResult (result, scope, keepAlive) {
|
|
866
787
|
var baseDraft = scope.drafts[0];
|
|
867
788
|
var isReplaced = result !== undefined && result !== baseDraft;
|
|
868
789
|
this.willFinalize(scope, result, isReplaced);
|
|
869
|
-
|
|
870
790
|
if (isReplaced) {
|
|
871
791
|
if (baseDraft[DRAFT_STATE].modified) {
|
|
872
792
|
scope.revoke(keepAlive);
|
|
@@ -877,7 +797,6 @@ Immer.prototype.processResult = function processResult (result, scope, keepAlive
|
|
|
877
797
|
// Finalize the result in case it contains (or is) a subset of the draft.
|
|
878
798
|
result = this.finalize(result, null, scope);
|
|
879
799
|
}
|
|
880
|
-
|
|
881
800
|
if (scope.patches) {
|
|
882
801
|
scope.patches.push({
|
|
883
802
|
op: "replace",
|
|
@@ -894,13 +813,10 @@ Immer.prototype.processResult = function processResult (result, scope, keepAlive
|
|
|
894
813
|
// Finalize the base draft.
|
|
895
814
|
result = this.finalize(baseDraft, [], scope, keepAlive);
|
|
896
815
|
}
|
|
897
|
-
|
|
898
816
|
scope.revoke(keepAlive);
|
|
899
|
-
|
|
900
817
|
if (scope.patches) {
|
|
901
818
|
scope.patchListener(scope.patches, scope.inversePatches);
|
|
902
819
|
}
|
|
903
|
-
|
|
904
820
|
return result !== NOTHING ? result : undefined;
|
|
905
821
|
};
|
|
906
822
|
/**
|
|
@@ -908,36 +824,28 @@ Immer.prototype.processResult = function processResult (result, scope, keepAlive
|
|
|
908
824
|
* Finalize a draft, returning either the unmodified base state or a modified
|
|
909
825
|
* copy of the base state.
|
|
910
826
|
*/
|
|
911
|
-
|
|
912
|
-
|
|
913
827
|
Immer.prototype.finalize = function finalize (draft, path, scope, keepAlive) {
|
|
914
|
-
var this$1 = this;
|
|
828
|
+
var this$1$1 = this;
|
|
915
829
|
|
|
916
830
|
var state = draft[DRAFT_STATE];
|
|
917
|
-
|
|
918
831
|
if (!state) {
|
|
919
832
|
if (Object.isFrozen(draft)) { return draft; }
|
|
920
833
|
return this.finalizeTree(draft, null, scope);
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
|
|
834
|
+
}
|
|
835
|
+
// Never finalize drafts owned by another scope.
|
|
924
836
|
if (state.scope !== scope) {
|
|
925
837
|
return draft;
|
|
926
838
|
}
|
|
927
|
-
|
|
928
839
|
if (!state.modified) {
|
|
929
840
|
return state.base;
|
|
930
841
|
}
|
|
931
|
-
|
|
932
842
|
if (!state.finalized) {
|
|
933
843
|
if (!keepAlive) { state.finalized = true; }
|
|
934
844
|
this.finalizeTree(state.draft, path, scope);
|
|
935
|
-
|
|
936
845
|
if (this.onDelete) {
|
|
937
846
|
// The `assigned` object is unreliable with ES5 drafts.
|
|
938
847
|
if (this.useProxies) {
|
|
939
848
|
var assigned = state.assigned;
|
|
940
|
-
|
|
941
849
|
for (var prop in assigned) {
|
|
942
850
|
if (!assigned[prop]) { this.onDelete(state, prop); }
|
|
943
851
|
}
|
|
@@ -945,96 +853,89 @@ Immer.prototype.finalize = function finalize (draft, path, scope, keepAlive) {
|
|
|
945
853
|
var base = state.base;
|
|
946
854
|
var copy = state.copy;
|
|
947
855
|
each(base, function (prop) {
|
|
948
|
-
if (!has(copy, prop)) { this$1.onDelete(state, prop); }
|
|
856
|
+
if (!has(copy, prop)) { this$1$1.onDelete(state, prop); }
|
|
949
857
|
});
|
|
950
858
|
}
|
|
951
859
|
}
|
|
952
|
-
|
|
953
860
|
if (this.onCopy) {
|
|
954
861
|
this.onCopy(state);
|
|
955
|
-
}
|
|
956
|
-
// so we can be sure that `scope.canAutoFreeze` is accurate.
|
|
957
|
-
|
|
862
|
+
}
|
|
958
863
|
|
|
864
|
+
// At this point, all descendants of `state.copy` have been finalized,
|
|
865
|
+
// so we can be sure that `scope.canAutoFreeze` is accurate.
|
|
959
866
|
if (this.autoFreeze && scope.canAutoFreeze) {
|
|
960
867
|
Object.freeze(state.copy);
|
|
961
868
|
}
|
|
962
|
-
|
|
963
869
|
if (path && scope.patches) {
|
|
964
870
|
generatePatches(state, path, scope.patches, scope.inversePatches);
|
|
965
871
|
}
|
|
966
872
|
}
|
|
967
|
-
|
|
968
873
|
return state.copy;
|
|
969
874
|
};
|
|
970
875
|
/**
|
|
971
876
|
* @internal
|
|
972
877
|
* Finalize all drafts in the given state tree.
|
|
973
878
|
*/
|
|
974
|
-
|
|
975
|
-
|
|
976
879
|
Immer.prototype.finalizeTree = function finalizeTree (root, rootPath, scope) {
|
|
977
|
-
var this$1 = this;
|
|
880
|
+
var this$1$1 = this;
|
|
978
881
|
|
|
979
882
|
var state = root[DRAFT_STATE];
|
|
980
|
-
|
|
981
883
|
if (state) {
|
|
982
884
|
if (!this.useProxies) {
|
|
983
885
|
// Create the final copy, with added keys and without deleted keys.
|
|
984
886
|
state.copy = shallowCopy(state.draft, true);
|
|
985
887
|
}
|
|
986
|
-
|
|
987
888
|
root = state.copy;
|
|
988
889
|
}
|
|
989
|
-
|
|
990
890
|
var needPatches = !!rootPath && !!scope.patches;
|
|
991
|
-
|
|
992
891
|
var finalizeProperty = function (prop, value, parent) {
|
|
993
892
|
if (value === parent) {
|
|
994
893
|
throw Error("Immer forbids circular references");
|
|
995
|
-
}
|
|
996
|
-
|
|
894
|
+
}
|
|
997
895
|
|
|
896
|
+
// In the `finalizeTree` method, only the `root` object may be a draft.
|
|
998
897
|
var isDraftProp = !!state && parent === root;
|
|
999
|
-
|
|
1000
898
|
if (isDraft(value)) {
|
|
1001
|
-
var path = isDraftProp && needPatches && !state.assigned[prop] ? rootPath.concat(prop) : null;
|
|
899
|
+
var path = isDraftProp && needPatches && !state.assigned[prop] ? rootPath.concat(prop) : null;
|
|
1002
900
|
|
|
1003
|
-
|
|
901
|
+
// Drafts owned by `scope` are finalized here.
|
|
902
|
+
value = this$1$1.finalize(value, path, scope);
|
|
1004
903
|
|
|
904
|
+
// Drafts from another scope must prevent auto-freezing.
|
|
1005
905
|
if (isDraft(value)) {
|
|
1006
906
|
scope.canAutoFreeze = false;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
907
|
+
}
|
|
1009
908
|
|
|
909
|
+
// Preserve non-enumerable properties.
|
|
1010
910
|
if (Array.isArray(parent) || isEnumerable(parent, prop)) {
|
|
1011
911
|
parent[prop] = value;
|
|
1012
912
|
} else {
|
|
1013
913
|
Object.defineProperty(parent, prop, {
|
|
1014
914
|
value: value
|
|
1015
915
|
});
|
|
1016
|
-
}
|
|
1017
|
-
|
|
916
|
+
}
|
|
1018
917
|
|
|
918
|
+
// Unchanged drafts are never passed to the `onAssign` hook.
|
|
1019
919
|
if (isDraftProp && value === state.base[prop]) { return; }
|
|
1020
|
-
}
|
|
920
|
+
}
|
|
921
|
+
// Unchanged draft properties are ignored.
|
|
1021
922
|
else if (isDraftProp && is(value, state.base[prop])) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (isDraftProp && this$1.onAssign) {
|
|
1029
|
-
this$1.onAssign(state, prop, value);
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
// Search new objects for unfinalized drafts. Frozen objects should never contain drafts.
|
|
926
|
+
else if (isDraftable(value) && !Object.isFrozen(value)) {
|
|
927
|
+
each(value, finalizeProperty);
|
|
928
|
+
}
|
|
929
|
+
if (isDraftProp && this$1$1.onAssign) {
|
|
930
|
+
this$1$1.onAssign(state, prop, value);
|
|
1030
931
|
}
|
|
1031
932
|
};
|
|
1032
|
-
|
|
1033
933
|
each(root, finalizeProperty);
|
|
1034
934
|
return root;
|
|
1035
935
|
};
|
|
1036
936
|
|
|
1037
937
|
var immer = new Immer();
|
|
938
|
+
|
|
1038
939
|
/**
|
|
1039
940
|
* The `produce` function takes a value and a "recipe function" (whose
|
|
1040
941
|
* return value often depends on the base state). The recipe function is
|
|
@@ -1054,36 +955,36 @@ var immer = new Immer();
|
|
|
1054
955
|
* @param {Function} patchListener - optional function that will be called with all the patches produced here
|
|
1055
956
|
* @returns {any} a new state, or the initial state if nothing was modified
|
|
1056
957
|
*/
|
|
1057
|
-
|
|
1058
958
|
var produce = immer.produce;
|
|
959
|
+
|
|
1059
960
|
/**
|
|
1060
961
|
* Pass true to automatically freeze all copies created by Immer.
|
|
1061
962
|
*
|
|
1062
963
|
* By default, auto-freezing is disabled in production.
|
|
1063
964
|
*/
|
|
1064
|
-
|
|
1065
965
|
var setAutoFreeze = immer.setAutoFreeze.bind(immer);
|
|
966
|
+
|
|
1066
967
|
/**
|
|
1067
968
|
* Pass true to use the ES2015 `Proxy` class when creating drafts, which is
|
|
1068
969
|
* always faster than using ES5 proxies.
|
|
1069
970
|
*
|
|
1070
971
|
* By default, feature detection is used, so calling this is rarely necessary.
|
|
1071
972
|
*/
|
|
1072
|
-
|
|
1073
973
|
var setUseProxies = immer.setUseProxies.bind(immer);
|
|
974
|
+
|
|
1074
975
|
/**
|
|
1075
976
|
* Apply an array of Immer patches to the first argument.
|
|
1076
977
|
*
|
|
1077
978
|
* This function is a producer, which means copy-on-write is in effect.
|
|
1078
979
|
*/
|
|
980
|
+
var applyPatches = immer.applyPatches.bind(immer);
|
|
1079
981
|
|
|
1080
|
-
var applyPatches$1 = immer.applyPatches.bind(immer);
|
|
1081
982
|
/**
|
|
1082
983
|
* Create an Immer draft from the given base state, which may be a draft itself.
|
|
1083
984
|
* The draft can be modified until you finalize it with the `finishDraft` function.
|
|
1084
985
|
*/
|
|
1085
|
-
|
|
1086
986
|
var createDraft = immer.createDraft.bind(immer);
|
|
987
|
+
|
|
1087
988
|
/**
|
|
1088
989
|
* Finalize an Immer draft from a `createDraft` call, returning the base state
|
|
1089
990
|
* (if no changes were made) or a modified copy. The draft must *not* be
|
|
@@ -1092,9 +993,7 @@ var createDraft = immer.createDraft.bind(immer);
|
|
|
1092
993
|
* Pass a function as the 2nd argument to generate Immer patches based on the
|
|
1093
994
|
* changes that were made.
|
|
1094
995
|
*/
|
|
1095
|
-
|
|
1096
996
|
var finishDraft = immer.finishDraft.bind(immer);
|
|
1097
997
|
|
|
1098
|
-
export default produce;
|
|
1099
|
-
export { DRAFT_STATE, Immer, applyPatches$1 as applyPatches, createDraft, finishDraft, DRAFTABLE as immerable, isDraft, isDraftable, NOTHING as nothing, original, produce, setAutoFreeze, setUseProxies };
|
|
998
|
+
export { DRAFT_STATE, Immer, applyPatches, createDraft, produce as default, finishDraft, DRAFTABLE as immerable, isDraft, isDraftable, NOTHING as nothing, original, produce, setAutoFreeze, setUseProxies };
|
|
1100
999
|
//# sourceMappingURL=immer.module.js.map
|