UNPKG

37.8 kBJavaScriptView Raw
1"use strict";
2var __defProp = Object.defineProperty;
3var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4var __getOwnPropNames = Object.getOwnPropertyNames;
5var __hasOwnProp = Object.prototype.hasOwnProperty;
6var __export = (target, all) => {
7 for (var name in all)
8 __defProp(target, name, { get: all[name], enumerable: true });
9};
10var __copyProps = (to, from, except, desc) => {
11 if (from && typeof from === "object" || typeof from === "function") {
12 for (let key of __getOwnPropNames(from))
13 if (!__hasOwnProp.call(to, key) && key !== except)
14 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15 }
16 return to;
17};
18var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
20// src/immer.ts
21var immer_exports = {};
22__export(immer_exports, {
23 Immer: () => Immer2,
24 applyPatches: () => applyPatches,
25 castDraft: () => castDraft,
26 castImmutable: () => castImmutable,
27 createDraft: () => createDraft,
28 current: () => current,
29 enableMapSet: () => enableMapSet,
30 enablePatches: () => enablePatches,
31 finishDraft: () => finishDraft,
32 freeze: () => freeze,
33 immerable: () => DRAFTABLE,
34 isDraft: () => isDraft,
35 isDraftable: () => isDraftable,
36 nothing: () => NOTHING,
37 original: () => original,
38 produce: () => produce,
39 produceWithPatches: () => produceWithPatches,
40 setAutoFreeze: () => setAutoFreeze,
41 setUseStrictShallowCopy: () => setUseStrictShallowCopy
42});
43module.exports = __toCommonJS(immer_exports);
44
45// src/utils/env.ts
46var NOTHING = Symbol.for("immer-nothing");
47var DRAFTABLE = Symbol.for("immer-draftable");
48var DRAFT_STATE = Symbol.for("immer-state");
49
50// src/utils/errors.ts
51var errors = process.env.NODE_ENV !== "production" ? [
52 // All error codes, starting by 0:
53 function(plugin) {
54 return `The plugin for '${plugin}' has not been loaded into Immer. To enable the plugin, import and call \`enable${plugin}()\` when initializing your application.`;
55 },
56 function(thing) {
57 return `produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '${thing}'`;
58 },
59 "This object has been frozen and should not be mutated",
60 function(data) {
61 return "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + data;
62 },
63 "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.",
64 "Immer forbids circular references",
65 "The first or second argument to `produce` must be a function",
66 "The third argument to `produce` must be a function or undefined",
67 "First argument to `createDraft` must be a plain object, an array, or an immerable object",
68 "First argument to `finishDraft` must be a draft returned by `createDraft`",
69 function(thing) {
70 return `'current' expects a draft, got: ${thing}`;
71 },
72 "Object.defineProperty() cannot be used on an Immer draft",
73 "Object.setPrototypeOf() cannot be used on an Immer draft",
74 "Immer only supports deleting array indices",
75 "Immer only supports setting array indices and the 'length' property",
76 function(thing) {
77 return `'original' expects a draft, got: ${thing}`;
78 }
79 // Note: if more errors are added, the errorOffset in Patches.ts should be increased
80 // See Patches.ts for additional errors
81] : [];
82function die(error, ...args) {
83 if (process.env.NODE_ENV !== "production") {
84 const e = errors[error];
85 const msg = typeof e === "function" ? e.apply(null, args) : e;
86 throw new Error(`[Immer] ${msg}`);
87 }
88 throw new Error(
89 `[Immer] minified error nr: ${error}. Full error at: https://bit.ly/3cXEKWf`
90 );
91}
92
93// src/utils/common.ts
94var getPrototypeOf = Object.getPrototypeOf;
95function isDraft(value) {
96 return !!value && !!value[DRAFT_STATE];
97}
98function isDraftable(value) {
99 if (!value)
100 return false;
101 return isPlainObject(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!value.constructor?.[DRAFTABLE] || isMap(value) || isSet(value);
102}
103var objectCtorString = Object.prototype.constructor.toString();
104function isPlainObject(value) {
105 if (!value || typeof value !== "object")
106 return false;
107 const proto = getPrototypeOf(value);
108 if (proto === null) {
109 return true;
110 }
111 const Ctor = Object.hasOwnProperty.call(proto, "constructor") && proto.constructor;
112 if (Ctor === Object)
113 return true;
114 return typeof Ctor == "function" && Function.toString.call(Ctor) === objectCtorString;
115}
116function original(value) {
117 if (!isDraft(value))
118 die(15, value);
119 return value[DRAFT_STATE].base_;
120}
121function each(obj, iter) {
122 if (getArchtype(obj) === 0 /* Object */) {
123 Reflect.ownKeys(obj).forEach((key) => {
124 iter(key, obj[key], obj);
125 });
126 } else {
127 obj.forEach((entry, index) => iter(index, entry, obj));
128 }
129}
130function getArchtype(thing) {
131 const state = thing[DRAFT_STATE];
132 return state ? state.type_ : Array.isArray(thing) ? 1 /* Array */ : isMap(thing) ? 2 /* Map */ : isSet(thing) ? 3 /* Set */ : 0 /* Object */;
133}
134function has(thing, prop) {
135 return getArchtype(thing) === 2 /* Map */ ? thing.has(prop) : Object.prototype.hasOwnProperty.call(thing, prop);
136}
137function get(thing, prop) {
138 return getArchtype(thing) === 2 /* Map */ ? thing.get(prop) : thing[prop];
139}
140function set(thing, propOrOldValue, value) {
141 const t = getArchtype(thing);
142 if (t === 2 /* Map */)
143 thing.set(propOrOldValue, value);
144 else if (t === 3 /* Set */) {
145 thing.add(value);
146 } else
147 thing[propOrOldValue] = value;
148}
149function is(x, y) {
150 if (x === y) {
151 return x !== 0 || 1 / x === 1 / y;
152 } else {
153 return x !== x && y !== y;
154 }
155}
156function isMap(target) {
157 return target instanceof Map;
158}
159function isSet(target) {
160 return target instanceof Set;
161}
162function latest(state) {
163 return state.copy_ || state.base_;
164}
165function shallowCopy(base, strict) {
166 if (isMap(base)) {
167 return new Map(base);
168 }
169 if (isSet(base)) {
170 return new Set(base);
171 }
172 if (Array.isArray(base))
173 return Array.prototype.slice.call(base);
174 const isPlain = isPlainObject(base);
175 if (strict === true || strict === "class_only" && !isPlain) {
176 const descriptors = Object.getOwnPropertyDescriptors(base);
177 delete descriptors[DRAFT_STATE];
178 let keys = Reflect.ownKeys(descriptors);
179 for (let i = 0; i < keys.length; i++) {
180 const key = keys[i];
181 const desc = descriptors[key];
182 if (desc.writable === false) {
183 desc.writable = true;
184 desc.configurable = true;
185 }
186 if (desc.get || desc.set)
187 descriptors[key] = {
188 configurable: true,
189 writable: true,
190 // could live with !!desc.set as well here...
191 enumerable: desc.enumerable,
192 value: base[key]
193 };
194 }
195 return Object.create(getPrototypeOf(base), descriptors);
196 } else {
197 const proto = getPrototypeOf(base);
198 if (proto !== null && isPlain) {
199 return { ...base };
200 }
201 const obj = Object.create(proto);
202 return Object.assign(obj, base);
203 }
204}
205function freeze(obj, deep = false) {
206 if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj))
207 return obj;
208 if (getArchtype(obj) > 1) {
209 obj.set = obj.add = obj.clear = obj.delete = dontMutateFrozenCollections;
210 }
211 Object.freeze(obj);
212 if (deep)
213 Object.entries(obj).forEach(([key, value]) => freeze(value, true));
214 return obj;
215}
216function dontMutateFrozenCollections() {
217 die(2);
218}
219function isFrozen(obj) {
220 return Object.isFrozen(obj);
221}
222
223// src/utils/plugins.ts
224var plugins = {};
225function getPlugin(pluginKey) {
226 const plugin = plugins[pluginKey];
227 if (!plugin) {
228 die(0, pluginKey);
229 }
230 return plugin;
231}
232function loadPlugin(pluginKey, implementation) {
233 if (!plugins[pluginKey])
234 plugins[pluginKey] = implementation;
235}
236
237// src/core/scope.ts
238var currentScope;
239function getCurrentScope() {
240 return currentScope;
241}
242function createScope(parent_, immer_) {
243 return {
244 drafts_: [],
245 parent_,
246 immer_,
247 // Whenever the modified draft contains a draft from another scope, we
248 // need to prevent auto-freezing so the unowned draft can be finalized.
249 canAutoFreeze_: true,
250 unfinalizedDrafts_: 0
251 };
252}
253function usePatchesInScope(scope, patchListener) {
254 if (patchListener) {
255 getPlugin("Patches");
256 scope.patches_ = [];
257 scope.inversePatches_ = [];
258 scope.patchListener_ = patchListener;
259 }
260}
261function revokeScope(scope) {
262 leaveScope(scope);
263 scope.drafts_.forEach(revokeDraft);
264 scope.drafts_ = null;
265}
266function leaveScope(scope) {
267 if (scope === currentScope) {
268 currentScope = scope.parent_;
269 }
270}
271function enterScope(immer2) {
272 return currentScope = createScope(currentScope, immer2);
273}
274function revokeDraft(draft) {
275 const state = draft[DRAFT_STATE];
276 if (state.type_ === 0 /* Object */ || state.type_ === 1 /* Array */)
277 state.revoke_();
278 else
279 state.revoked_ = true;
280}
281
282// src/core/finalize.ts
283function processResult(result, scope) {
284 scope.unfinalizedDrafts_ = scope.drafts_.length;
285 const baseDraft = scope.drafts_[0];
286 const isReplaced = result !== void 0 && result !== baseDraft;
287 if (isReplaced) {
288 if (baseDraft[DRAFT_STATE].modified_) {
289 revokeScope(scope);
290 die(4);
291 }
292 if (isDraftable(result)) {
293 result = finalize(scope, result);
294 if (!scope.parent_)
295 maybeFreeze(scope, result);
296 }
297 if (scope.patches_) {
298 getPlugin("Patches").generateReplacementPatches_(
299 baseDraft[DRAFT_STATE].base_,
300 result,
301 scope.patches_,
302 scope.inversePatches_
303 );
304 }
305 } else {
306 result = finalize(scope, baseDraft, []);
307 }
308 revokeScope(scope);
309 if (scope.patches_) {
310 scope.patchListener_(scope.patches_, scope.inversePatches_);
311 }
312 return result !== NOTHING ? result : void 0;
313}
314function finalize(rootScope, value, path) {
315 if (isFrozen(value))
316 return value;
317 const state = value[DRAFT_STATE];
318 if (!state) {
319 each(
320 value,
321 (key, childValue) => finalizeProperty(rootScope, state, value, key, childValue, path)
322 );
323 return value;
324 }
325 if (state.scope_ !== rootScope)
326 return value;
327 if (!state.modified_) {
328 maybeFreeze(rootScope, state.base_, true);
329 return state.base_;
330 }
331 if (!state.finalized_) {
332 state.finalized_ = true;
333 state.scope_.unfinalizedDrafts_--;
334 const result = state.copy_;
335 let resultEach = result;
336 let isSet2 = false;
337 if (state.type_ === 3 /* Set */) {
338 resultEach = new Set(result);
339 result.clear();
340 isSet2 = true;
341 }
342 each(
343 resultEach,
344 (key, childValue) => finalizeProperty(rootScope, state, result, key, childValue, path, isSet2)
345 );
346 maybeFreeze(rootScope, result, false);
347 if (path && rootScope.patches_) {
348 getPlugin("Patches").generatePatches_(
349 state,
350 path,
351 rootScope.patches_,
352 rootScope.inversePatches_
353 );
354 }
355 }
356 return state.copy_;
357}
358function finalizeProperty(rootScope, parentState, targetObject, prop, childValue, rootPath, targetIsSet) {
359 if (process.env.NODE_ENV !== "production" && childValue === targetObject)
360 die(5);
361 if (isDraft(childValue)) {
362 const path = rootPath && parentState && parentState.type_ !== 3 /* Set */ && // Set objects are atomic since they have no keys.
363 !has(parentState.assigned_, prop) ? rootPath.concat(prop) : void 0;
364 const res = finalize(rootScope, childValue, path);
365 set(targetObject, prop, res);
366 if (isDraft(res)) {
367 rootScope.canAutoFreeze_ = false;
368 } else
369 return;
370 } else if (targetIsSet) {
371 targetObject.add(childValue);
372 }
373 if (isDraftable(childValue) && !isFrozen(childValue)) {
374 if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) {
375 return;
376 }
377 finalize(rootScope, childValue);
378 if ((!parentState || !parentState.scope_.parent_) && typeof prop !== "symbol" && Object.prototype.propertyIsEnumerable.call(targetObject, prop))
379 maybeFreeze(rootScope, childValue);
380 }
381}
382function maybeFreeze(scope, value, deep = false) {
383 if (!scope.parent_ && scope.immer_.autoFreeze_ && scope.canAutoFreeze_) {
384 freeze(value, deep);
385 }
386}
387
388// src/core/proxy.ts
389function createProxyProxy(base, parent) {
390 const isArray = Array.isArray(base);
391 const state = {
392 type_: isArray ? 1 /* Array */ : 0 /* Object */,
393 // Track which produce call this is associated with.
394 scope_: parent ? parent.scope_ : getCurrentScope(),
395 // True for both shallow and deep changes.
396 modified_: false,
397 // Used during finalization.
398 finalized_: false,
399 // Track which properties have been assigned (true) or deleted (false).
400 assigned_: {},
401 // The parent draft state.
402 parent_: parent,
403 // The base state.
404 base_: base,
405 // The base proxy.
406 draft_: null,
407 // set below
408 // The base copy with any updated values.
409 copy_: null,
410 // Called by the `produce` function.
411 revoke_: null,
412 isManual_: false
413 };
414 let target = state;
415 let traps = objectTraps;
416 if (isArray) {
417 target = [state];
418 traps = arrayTraps;
419 }
420 const { revoke, proxy } = Proxy.revocable(target, traps);
421 state.draft_ = proxy;
422 state.revoke_ = revoke;
423 return proxy;
424}
425var objectTraps = {
426 get(state, prop) {
427 if (prop === DRAFT_STATE)
428 return state;
429 const source = latest(state);
430 if (!has(source, prop)) {
431 return readPropFromProto(state, source, prop);
432 }
433 const value = source[prop];
434 if (state.finalized_ || !isDraftable(value)) {
435 return value;
436 }
437 if (value === peek(state.base_, prop)) {
438 prepareCopy(state);
439 return state.copy_[prop] = createProxy(value, state);
440 }
441 return value;
442 },
443 has(state, prop) {
444 return prop in latest(state);
445 },
446 ownKeys(state) {
447 return Reflect.ownKeys(latest(state));
448 },
449 set(state, prop, value) {
450 const desc = getDescriptorFromProto(latest(state), prop);
451 if (desc?.set) {
452 desc.set.call(state.draft_, value);
453 return true;
454 }
455 if (!state.modified_) {
456 const current2 = peek(latest(state), prop);
457 const currentState = current2?.[DRAFT_STATE];
458 if (currentState && currentState.base_ === value) {
459 state.copy_[prop] = value;
460 state.assigned_[prop] = false;
461 return true;
462 }
463 if (is(value, current2) && (value !== void 0 || has(state.base_, prop)))
464 return true;
465 prepareCopy(state);
466 markChanged(state);
467 }
468 if (state.copy_[prop] === value && // special case: handle new props with value 'undefined'
469 (value !== void 0 || prop in state.copy_) || // special case: NaN
470 Number.isNaN(value) && Number.isNaN(state.copy_[prop]))
471 return true;
472 state.copy_[prop] = value;
473 state.assigned_[prop] = true;
474 return true;
475 },
476 deleteProperty(state, prop) {
477 if (peek(state.base_, prop) !== void 0 || prop in state.base_) {
478 state.assigned_[prop] = false;
479 prepareCopy(state);
480 markChanged(state);
481 } else {
482 delete state.assigned_[prop];
483 }
484 if (state.copy_) {
485 delete state.copy_[prop];
486 }
487 return true;
488 },
489 // Note: We never coerce `desc.value` into an Immer draft, because we can't make
490 // the same guarantee in ES5 mode.
491 getOwnPropertyDescriptor(state, prop) {
492 const owner = latest(state);
493 const desc = Reflect.getOwnPropertyDescriptor(owner, prop);
494 if (!desc)
495 return desc;
496 return {
497 writable: true,
498 configurable: state.type_ !== 1 /* Array */ || prop !== "length",
499 enumerable: desc.enumerable,
500 value: owner[prop]
501 };
502 },
503 defineProperty() {
504 die(11);
505 },
506 getPrototypeOf(state) {
507 return getPrototypeOf(state.base_);
508 },
509 setPrototypeOf() {
510 die(12);
511 }
512};
513var arrayTraps = {};
514each(objectTraps, (key, fn) => {
515 arrayTraps[key] = function() {
516 arguments[0] = arguments[0][0];
517 return fn.apply(this, arguments);
518 };
519});
520arrayTraps.deleteProperty = function(state, prop) {
521 if (process.env.NODE_ENV !== "production" && isNaN(parseInt(prop)))
522 die(13);
523 return arrayTraps.set.call(this, state, prop, void 0);
524};
525arrayTraps.set = function(state, prop, value) {
526 if (process.env.NODE_ENV !== "production" && prop !== "length" && isNaN(parseInt(prop)))
527 die(14);
528 return objectTraps.set.call(this, state[0], prop, value, state[0]);
529};
530function peek(draft, prop) {
531 const state = draft[DRAFT_STATE];
532 const source = state ? latest(state) : draft;
533 return source[prop];
534}
535function readPropFromProto(state, source, prop) {
536 const desc = getDescriptorFromProto(source, prop);
537 return desc ? `value` in desc ? desc.value : (
538 // This is a very special case, if the prop is a getter defined by the
539 // prototype, we should invoke it with the draft as context!
540 desc.get?.call(state.draft_)
541 ) : void 0;
542}
543function getDescriptorFromProto(source, prop) {
544 if (!(prop in source))
545 return void 0;
546 let proto = getPrototypeOf(source);
547 while (proto) {
548 const desc = Object.getOwnPropertyDescriptor(proto, prop);
549 if (desc)
550 return desc;
551 proto = getPrototypeOf(proto);
552 }
553 return void 0;
554}
555function markChanged(state) {
556 if (!state.modified_) {
557 state.modified_ = true;
558 if (state.parent_) {
559 markChanged(state.parent_);
560 }
561 }
562}
563function prepareCopy(state) {
564 if (!state.copy_) {
565 state.copy_ = shallowCopy(
566 state.base_,
567 state.scope_.immer_.useStrictShallowCopy_
568 );
569 }
570}
571
572// src/core/immerClass.ts
573var Immer2 = class {
574 constructor(config) {
575 this.autoFreeze_ = true;
576 this.useStrictShallowCopy_ = false;
577 /**
578 * The `produce` function takes a value and a "recipe function" (whose
579 * return value often depends on the base state). The recipe function is
580 * free to mutate its first argument however it wants. All mutations are
581 * only ever applied to a __copy__ of the base state.
582 *
583 * Pass only a function to create a "curried producer" which relieves you
584 * from passing the recipe function every time.
585 *
586 * Only plain objects and arrays are made mutable. All other objects are
587 * considered uncopyable.
588 *
589 * Note: This function is __bound__ to its `Immer` instance.
590 *
591 * @param {any} base - the initial state
592 * @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified
593 * @param {Function} patchListener - optional function that will be called with all the patches produced here
594 * @returns {any} a new state, or the initial state if nothing was modified
595 */
596 this.produce = (base, recipe, patchListener) => {
597 if (typeof base === "function" && typeof recipe !== "function") {
598 const defaultBase = recipe;
599 recipe = base;
600 const self = this;
601 return function curriedProduce(base2 = defaultBase, ...args) {
602 return self.produce(base2, (draft) => recipe.call(this, draft, ...args));
603 };
604 }
605 if (typeof recipe !== "function")
606 die(6);
607 if (patchListener !== void 0 && typeof patchListener !== "function")
608 die(7);
609 let result;
610 if (isDraftable(base)) {
611 const scope = enterScope(this);
612 const proxy = createProxy(base, void 0);
613 let hasError = true;
614 try {
615 result = recipe(proxy);
616 hasError = false;
617 } finally {
618 if (hasError)
619 revokeScope(scope);
620 else
621 leaveScope(scope);
622 }
623 usePatchesInScope(scope, patchListener);
624 return processResult(result, scope);
625 } else if (!base || typeof base !== "object") {
626 result = recipe(base);
627 if (result === void 0)
628 result = base;
629 if (result === NOTHING)
630 result = void 0;
631 if (this.autoFreeze_)
632 freeze(result, true);
633 if (patchListener) {
634 const p = [];
635 const ip = [];
636 getPlugin("Patches").generateReplacementPatches_(base, result, p, ip);
637 patchListener(p, ip);
638 }
639 return result;
640 } else
641 die(1, base);
642 };
643 this.produceWithPatches = (base, recipe) => {
644 if (typeof base === "function") {
645 return (state, ...args) => this.produceWithPatches(state, (draft) => base(draft, ...args));
646 }
647 let patches, inversePatches;
648 const result = this.produce(base, recipe, (p, ip) => {
649 patches = p;
650 inversePatches = ip;
651 });
652 return [result, patches, inversePatches];
653 };
654 if (typeof config?.autoFreeze === "boolean")
655 this.setAutoFreeze(config.autoFreeze);
656 if (typeof config?.useStrictShallowCopy === "boolean")
657 this.setUseStrictShallowCopy(config.useStrictShallowCopy);
658 }
659 createDraft(base) {
660 if (!isDraftable(base))
661 die(8);
662 if (isDraft(base))
663 base = current(base);
664 const scope = enterScope(this);
665 const proxy = createProxy(base, void 0);
666 proxy[DRAFT_STATE].isManual_ = true;
667 leaveScope(scope);
668 return proxy;
669 }
670 finishDraft(draft, patchListener) {
671 const state = draft && draft[DRAFT_STATE];
672 if (!state || !state.isManual_)
673 die(9);
674 const { scope_: scope } = state;
675 usePatchesInScope(scope, patchListener);
676 return processResult(void 0, scope);
677 }
678 /**
679 * Pass true to automatically freeze all copies created by Immer.
680 *
681 * By default, auto-freezing is enabled.
682 */
683 setAutoFreeze(value) {
684 this.autoFreeze_ = value;
685 }
686 /**
687 * Pass true to enable strict shallow copy.
688 *
689 * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
690 */
691 setUseStrictShallowCopy(value) {
692 this.useStrictShallowCopy_ = value;
693 }
694 applyPatches(base, patches) {
695 let i;
696 for (i = patches.length - 1; i >= 0; i--) {
697 const patch = patches[i];
698 if (patch.path.length === 0 && patch.op === "replace") {
699 base = patch.value;
700 break;
701 }
702 }
703 if (i > -1) {
704 patches = patches.slice(i + 1);
705 }
706 const applyPatchesImpl = getPlugin("Patches").applyPatches_;
707 if (isDraft(base)) {
708 return applyPatchesImpl(base, patches);
709 }
710 return this.produce(
711 base,
712 (draft) => applyPatchesImpl(draft, patches)
713 );
714 }
715};
716function createProxy(value, parent) {
717 const draft = isMap(value) ? getPlugin("MapSet").proxyMap_(value, parent) : isSet(value) ? getPlugin("MapSet").proxySet_(value, parent) : createProxyProxy(value, parent);
718 const scope = parent ? parent.scope_ : getCurrentScope();
719 scope.drafts_.push(draft);
720 return draft;
721}
722
723// src/core/current.ts
724function current(value) {
725 if (!isDraft(value))
726 die(10, value);
727 return currentImpl(value);
728}
729function currentImpl(value) {
730 if (!isDraftable(value) || isFrozen(value))
731 return value;
732 const state = value[DRAFT_STATE];
733 let copy;
734 if (state) {
735 if (!state.modified_)
736 return state.base_;
737 state.finalized_ = true;
738 copy = shallowCopy(value, state.scope_.immer_.useStrictShallowCopy_);
739 } else {
740 copy = shallowCopy(value, true);
741 }
742 each(copy, (key, childValue) => {
743 set(copy, key, currentImpl(childValue));
744 });
745 if (state) {
746 state.finalized_ = false;
747 }
748 return copy;
749}
750
751// src/plugins/patches.ts
752function enablePatches() {
753 const errorOffset = 16;
754 if (process.env.NODE_ENV !== "production") {
755 errors.push(
756 'Sets cannot have "replace" patches.',
757 function(op) {
758 return "Unsupported patch operation: " + op;
759 },
760 function(path) {
761 return "Cannot apply patch, path doesn't resolve: " + path;
762 },
763 "Patching reserved attributes like __proto__, prototype and constructor is not allowed"
764 );
765 }
766 const REPLACE = "replace";
767 const ADD = "add";
768 const REMOVE = "remove";
769 function generatePatches_(state, basePath, patches, inversePatches) {
770 switch (state.type_) {
771 case 0 /* Object */:
772 case 2 /* Map */:
773 return generatePatchesFromAssigned(
774 state,
775 basePath,
776 patches,
777 inversePatches
778 );
779 case 1 /* Array */:
780 return generateArrayPatches(state, basePath, patches, inversePatches);
781 case 3 /* Set */:
782 return generateSetPatches(
783 state,
784 basePath,
785 patches,
786 inversePatches
787 );
788 }
789 }
790 function generateArrayPatches(state, basePath, patches, inversePatches) {
791 let { base_, assigned_ } = state;
792 let copy_ = state.copy_;
793 if (copy_.length < base_.length) {
794 ;
795 [base_, copy_] = [copy_, base_];
796 [patches, inversePatches] = [inversePatches, patches];
797 }
798 for (let i = 0; i < base_.length; i++) {
799 if (assigned_[i] && copy_[i] !== base_[i]) {
800 const path = basePath.concat([i]);
801 patches.push({
802 op: REPLACE,
803 path,
804 // Need to maybe clone it, as it can in fact be the original value
805 // due to the base/copy inversion at the start of this function
806 value: clonePatchValueIfNeeded(copy_[i])
807 });
808 inversePatches.push({
809 op: REPLACE,
810 path,
811 value: clonePatchValueIfNeeded(base_[i])
812 });
813 }
814 }
815 for (let i = base_.length; i < copy_.length; i++) {
816 const path = basePath.concat([i]);
817 patches.push({
818 op: ADD,
819 path,
820 // Need to maybe clone it, as it can in fact be the original value
821 // due to the base/copy inversion at the start of this function
822 value: clonePatchValueIfNeeded(copy_[i])
823 });
824 }
825 for (let i = copy_.length - 1; base_.length <= i; --i) {
826 const path = basePath.concat([i]);
827 inversePatches.push({
828 op: REMOVE,
829 path
830 });
831 }
832 }
833 function generatePatchesFromAssigned(state, basePath, patches, inversePatches) {
834 const { base_, copy_ } = state;
835 each(state.assigned_, (key, assignedValue) => {
836 const origValue = get(base_, key);
837 const value = get(copy_, key);
838 const op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD;
839 if (origValue === value && op === REPLACE)
840 return;
841 const path = basePath.concat(key);
842 patches.push(op === REMOVE ? { op, path } : { op, path, value });
843 inversePatches.push(
844 op === ADD ? { op: REMOVE, path } : op === REMOVE ? { op: ADD, path, value: clonePatchValueIfNeeded(origValue) } : { op: REPLACE, path, value: clonePatchValueIfNeeded(origValue) }
845 );
846 });
847 }
848 function generateSetPatches(state, basePath, patches, inversePatches) {
849 let { base_, copy_ } = state;
850 let i = 0;
851 base_.forEach((value) => {
852 if (!copy_.has(value)) {
853 const path = basePath.concat([i]);
854 patches.push({
855 op: REMOVE,
856 path,
857 value
858 });
859 inversePatches.unshift({
860 op: ADD,
861 path,
862 value
863 });
864 }
865 i++;
866 });
867 i = 0;
868 copy_.forEach((value) => {
869 if (!base_.has(value)) {
870 const path = basePath.concat([i]);
871 patches.push({
872 op: ADD,
873 path,
874 value
875 });
876 inversePatches.unshift({
877 op: REMOVE,
878 path,
879 value
880 });
881 }
882 i++;
883 });
884 }
885 function generateReplacementPatches_(baseValue, replacement, patches, inversePatches) {
886 patches.push({
887 op: REPLACE,
888 path: [],
889 value: replacement === NOTHING ? void 0 : replacement
890 });
891 inversePatches.push({
892 op: REPLACE,
893 path: [],
894 value: baseValue
895 });
896 }
897 function applyPatches_(draft, patches) {
898 patches.forEach((patch) => {
899 const { path, op } = patch;
900 let base = draft;
901 for (let i = 0; i < path.length - 1; i++) {
902 const parentType = getArchtype(base);
903 let p = path[i];
904 if (typeof p !== "string" && typeof p !== "number") {
905 p = "" + p;
906 }
907 if ((parentType === 0 /* Object */ || parentType === 1 /* Array */) && (p === "__proto__" || p === "constructor"))
908 die(errorOffset + 3);
909 if (typeof base === "function" && p === "prototype")
910 die(errorOffset + 3);
911 base = get(base, p);
912 if (typeof base !== "object")
913 die(errorOffset + 2, path.join("/"));
914 }
915 const type = getArchtype(base);
916 const value = deepClonePatchValue(patch.value);
917 const key = path[path.length - 1];
918 switch (op) {
919 case REPLACE:
920 switch (type) {
921 case 2 /* Map */:
922 return base.set(key, value);
923 case 3 /* Set */:
924 die(errorOffset);
925 default:
926 return base[key] = value;
927 }
928 case ADD:
929 switch (type) {
930 case 1 /* Array */:
931 return key === "-" ? base.push(value) : base.splice(key, 0, value);
932 case 2 /* Map */:
933 return base.set(key, value);
934 case 3 /* Set */:
935 return base.add(value);
936 default:
937 return base[key] = value;
938 }
939 case REMOVE:
940 switch (type) {
941 case 1 /* Array */:
942 return base.splice(key, 1);
943 case 2 /* Map */:
944 return base.delete(key);
945 case 3 /* Set */:
946 return base.delete(patch.value);
947 default:
948 return delete base[key];
949 }
950 default:
951 die(errorOffset + 1, op);
952 }
953 });
954 return draft;
955 }
956 function deepClonePatchValue(obj) {
957 if (!isDraftable(obj))
958 return obj;
959 if (Array.isArray(obj))
960 return obj.map(deepClonePatchValue);
961 if (isMap(obj))
962 return new Map(
963 Array.from(obj.entries()).map(([k, v]) => [k, deepClonePatchValue(v)])
964 );
965 if (isSet(obj))
966 return new Set(Array.from(obj).map(deepClonePatchValue));
967 const cloned = Object.create(getPrototypeOf(obj));
968 for (const key in obj)
969 cloned[key] = deepClonePatchValue(obj[key]);
970 if (has(obj, DRAFTABLE))
971 cloned[DRAFTABLE] = obj[DRAFTABLE];
972 return cloned;
973 }
974 function clonePatchValueIfNeeded(obj) {
975 if (isDraft(obj)) {
976 return deepClonePatchValue(obj);
977 } else
978 return obj;
979 }
980 loadPlugin("Patches", {
981 applyPatches_,
982 generatePatches_,
983 generateReplacementPatches_
984 });
985}
986
987// src/plugins/mapset.ts
988function enableMapSet() {
989 class DraftMap extends Map {
990 constructor(target, parent) {
991 super();
992 this[DRAFT_STATE] = {
993 type_: 2 /* Map */,
994 parent_: parent,
995 scope_: parent ? parent.scope_ : getCurrentScope(),
996 modified_: false,
997 finalized_: false,
998 copy_: void 0,
999 assigned_: void 0,
1000 base_: target,
1001 draft_: this,
1002 isManual_: false,
1003 revoked_: false
1004 };
1005 }
1006 get size() {
1007 return latest(this[DRAFT_STATE]).size;
1008 }
1009 has(key) {
1010 return latest(this[DRAFT_STATE]).has(key);
1011 }
1012 set(key, value) {
1013 const state = this[DRAFT_STATE];
1014 assertUnrevoked(state);
1015 if (!latest(state).has(key) || latest(state).get(key) !== value) {
1016 prepareMapCopy(state);
1017 markChanged(state);
1018 state.assigned_.set(key, true);
1019 state.copy_.set(key, value);
1020 state.assigned_.set(key, true);
1021 }
1022 return this;
1023 }
1024 delete(key) {
1025 if (!this.has(key)) {
1026 return false;
1027 }
1028 const state = this[DRAFT_STATE];
1029 assertUnrevoked(state);
1030 prepareMapCopy(state);
1031 markChanged(state);
1032 if (state.base_.has(key)) {
1033 state.assigned_.set(key, false);
1034 } else {
1035 state.assigned_.delete(key);
1036 }
1037 state.copy_.delete(key);
1038 return true;
1039 }
1040 clear() {
1041 const state = this[DRAFT_STATE];
1042 assertUnrevoked(state);
1043 if (latest(state).size) {
1044 prepareMapCopy(state);
1045 markChanged(state);
1046 state.assigned_ = /* @__PURE__ */ new Map();
1047 each(state.base_, (key) => {
1048 state.assigned_.set(key, false);
1049 });
1050 state.copy_.clear();
1051 }
1052 }
1053 forEach(cb, thisArg) {
1054 const state = this[DRAFT_STATE];
1055 latest(state).forEach((_value, key, _map) => {
1056 cb.call(thisArg, this.get(key), key, this);
1057 });
1058 }
1059 get(key) {
1060 const state = this[DRAFT_STATE];
1061 assertUnrevoked(state);
1062 const value = latest(state).get(key);
1063 if (state.finalized_ || !isDraftable(value)) {
1064 return value;
1065 }
1066 if (value !== state.base_.get(key)) {
1067 return value;
1068 }
1069 const draft = createProxy(value, state);
1070 prepareMapCopy(state);
1071 state.copy_.set(key, draft);
1072 return draft;
1073 }
1074 keys() {
1075 return latest(this[DRAFT_STATE]).keys();
1076 }
1077 values() {
1078 const iterator = this.keys();
1079 return {
1080 [Symbol.iterator]: () => this.values(),
1081 next: () => {
1082 const r = iterator.next();
1083 if (r.done)
1084 return r;
1085 const value = this.get(r.value);
1086 return {
1087 done: false,
1088 value
1089 };
1090 }
1091 };
1092 }
1093 entries() {
1094 const iterator = this.keys();
1095 return {
1096 [Symbol.iterator]: () => this.entries(),
1097 next: () => {
1098 const r = iterator.next();
1099 if (r.done)
1100 return r;
1101 const value = this.get(r.value);
1102 return {
1103 done: false,
1104 value: [r.value, value]
1105 };
1106 }
1107 };
1108 }
1109 [(DRAFT_STATE, Symbol.iterator)]() {
1110 return this.entries();
1111 }
1112 }
1113 function proxyMap_(target, parent) {
1114 return new DraftMap(target, parent);
1115 }
1116 function prepareMapCopy(state) {
1117 if (!state.copy_) {
1118 state.assigned_ = /* @__PURE__ */ new Map();
1119 state.copy_ = new Map(state.base_);
1120 }
1121 }
1122 class DraftSet extends Set {
1123 constructor(target, parent) {
1124 super();
1125 this[DRAFT_STATE] = {
1126 type_: 3 /* Set */,
1127 parent_: parent,
1128 scope_: parent ? parent.scope_ : getCurrentScope(),
1129 modified_: false,
1130 finalized_: false,
1131 copy_: void 0,
1132 base_: target,
1133 draft_: this,
1134 drafts_: /* @__PURE__ */ new Map(),
1135 revoked_: false,
1136 isManual_: false
1137 };
1138 }
1139 get size() {
1140 return latest(this[DRAFT_STATE]).size;
1141 }
1142 has(value) {
1143 const state = this[DRAFT_STATE];
1144 assertUnrevoked(state);
1145 if (!state.copy_) {
1146 return state.base_.has(value);
1147 }
1148 if (state.copy_.has(value))
1149 return true;
1150 if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value)))
1151 return true;
1152 return false;
1153 }
1154 add(value) {
1155 const state = this[DRAFT_STATE];
1156 assertUnrevoked(state);
1157 if (!this.has(value)) {
1158 prepareSetCopy(state);
1159 markChanged(state);
1160 state.copy_.add(value);
1161 }
1162 return this;
1163 }
1164 delete(value) {
1165 if (!this.has(value)) {
1166 return false;
1167 }
1168 const state = this[DRAFT_STATE];
1169 assertUnrevoked(state);
1170 prepareSetCopy(state);
1171 markChanged(state);
1172 return state.copy_.delete(value) || (state.drafts_.has(value) ? state.copy_.delete(state.drafts_.get(value)) : (
1173 /* istanbul ignore next */
1174 false
1175 ));
1176 }
1177 clear() {
1178 const state = this[DRAFT_STATE];
1179 assertUnrevoked(state);
1180 if (latest(state).size) {
1181 prepareSetCopy(state);
1182 markChanged(state);
1183 state.copy_.clear();
1184 }
1185 }
1186 values() {
1187 const state = this[DRAFT_STATE];
1188 assertUnrevoked(state);
1189 prepareSetCopy(state);
1190 return state.copy_.values();
1191 }
1192 entries() {
1193 const state = this[DRAFT_STATE];
1194 assertUnrevoked(state);
1195 prepareSetCopy(state);
1196 return state.copy_.entries();
1197 }
1198 keys() {
1199 return this.values();
1200 }
1201 [(DRAFT_STATE, Symbol.iterator)]() {
1202 return this.values();
1203 }
1204 forEach(cb, thisArg) {
1205 const iterator = this.values();
1206 let result = iterator.next();
1207 while (!result.done) {
1208 cb.call(thisArg, result.value, result.value, this);
1209 result = iterator.next();
1210 }
1211 }
1212 }
1213 function proxySet_(target, parent) {
1214 return new DraftSet(target, parent);
1215 }
1216 function prepareSetCopy(state) {
1217 if (!state.copy_) {
1218 state.copy_ = /* @__PURE__ */ new Set();
1219 state.base_.forEach((value) => {
1220 if (isDraftable(value)) {
1221 const draft = createProxy(value, state);
1222 state.drafts_.set(value, draft);
1223 state.copy_.add(draft);
1224 } else {
1225 state.copy_.add(value);
1226 }
1227 });
1228 }
1229 }
1230 function assertUnrevoked(state) {
1231 if (state.revoked_)
1232 die(3, JSON.stringify(latest(state)));
1233 }
1234 loadPlugin("MapSet", { proxyMap_, proxySet_ });
1235}
1236
1237// src/immer.ts
1238var immer = new Immer2();
1239var produce = immer.produce;
1240var produceWithPatches = immer.produceWithPatches.bind(
1241 immer
1242);
1243var setAutoFreeze = immer.setAutoFreeze.bind(immer);
1244var setUseStrictShallowCopy = immer.setUseStrictShallowCopy.bind(immer);
1245var applyPatches = immer.applyPatches.bind(immer);
1246var createDraft = immer.createDraft.bind(immer);
1247var finishDraft = immer.finishDraft.bind(immer);
1248function castDraft(value) {
1249 return value;
1250}
1251function castImmutable(value) {
1252 return value;
1253}
1254// Annotate the CommonJS export names for ESM import in node:
12550 && (module.exports = {
1256 Immer,
1257 applyPatches,
1258 castDraft,
1259 castImmutable,
1260 createDraft,
1261 current,
1262 enableMapSet,
1263 enablePatches,
1264 finishDraft,
1265 freeze,
1266 immerable,
1267 isDraft,
1268 isDraftable,
1269 nothing,
1270 original,
1271 produce,
1272 produceWithPatches,
1273 setAutoFreeze,
1274 setUseStrictShallowCopy
1275});
1276//# sourceMappingURL=immer.cjs.development.js.map
\No newline at end of file