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