Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

757 строки
26 KiB

  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. function generatePatches(state, basepath, patches, inversePatches, baseValue, resultValue) {
  4. if (patches) if (Array.isArray(baseValue)) generateArrayPatches(state, basepath, patches, inversePatches, baseValue, resultValue);else generateObjectPatches(state, basepath, patches, inversePatches, baseValue, resultValue);
  5. }
  6. function generateArrayPatches(state, basepath, patches, inversePatches, baseValue, resultValue) {
  7. var shared = Math.min(baseValue.length, resultValue.length);
  8. for (var i = 0; i < shared; i++) {
  9. if (state.assigned[i] && baseValue[i] !== resultValue[i]) {
  10. var path = basepath.concat(i);
  11. patches.push({ op: "replace", path: path, value: resultValue[i] });
  12. inversePatches.push({ op: "replace", path: path, value: baseValue[i] });
  13. }
  14. }
  15. if (shared < resultValue.length) {
  16. // stuff was added
  17. for (var _i = shared; _i < resultValue.length; _i++) {
  18. var _path = basepath.concat(_i);
  19. patches.push({ op: "add", path: _path, value: resultValue[_i] });
  20. }
  21. inversePatches.push({
  22. op: "replace",
  23. path: basepath.concat("length"),
  24. value: baseValue.length
  25. });
  26. } else if (shared < baseValue.length) {
  27. // stuff was removed
  28. patches.push({
  29. op: "replace",
  30. path: basepath.concat("length"),
  31. value: resultValue.length
  32. });
  33. for (var _i2 = shared; _i2 < baseValue.length; _i2++) {
  34. var _path2 = basepath.concat(_i2);
  35. inversePatches.push({ op: "add", path: _path2, value: baseValue[_i2] });
  36. }
  37. }
  38. }
  39. function generateObjectPatches(state, basepath, patches, inversePatches, baseValue, resultValue) {
  40. each(state.assigned, function (key, assignedValue) {
  41. var origValue = baseValue[key];
  42. var value = resultValue[key];
  43. var op = !assignedValue ? "remove" : key in baseValue ? "replace" : "add";
  44. if (origValue === baseValue && op === "replace") return;
  45. var path = basepath.concat(key);
  46. patches.push(op === "remove" ? { op: op, path: path } : { op: op, path: path, value: value });
  47. inversePatches.push(op === "add" ? { op: "remove", path: path } : op === "remove" ? { op: "add", path: path, value: origValue } : { op: "replace", path: path, value: origValue });
  48. });
  49. }
  50. function applyPatches(draft, patches) {
  51. var _loop = function _loop(i) {
  52. var patch = patches[i];
  53. if (patch.path.length === 0 && patch.op === "replace") {
  54. draft = patch.value;
  55. } else {
  56. var path = patch.path.slice();
  57. var key = path.pop();
  58. var base = path.reduce(function (current, part) {
  59. if (!current) throw new Error("Cannot apply patch, path doesn't resolve: " + patch.path.join("/"));
  60. return current[part];
  61. }, draft);
  62. if (!base) throw new Error("Cannot apply patch, path doesn't resolve: " + patch.path.join("/"));
  63. switch (patch.op) {
  64. case "replace":
  65. case "add":
  66. // TODO: add support is not extensive, it does not support insertion or `-` atm!
  67. base[key] = patch.value;
  68. break;
  69. case "remove":
  70. if (Array.isArray(base)) {
  71. if (key === base.length - 1) base.length -= 1;else throw new Error("Remove can only remove the last key of an array, index: " + key + ", length: " + base.length);
  72. } else delete base[key];
  73. break;
  74. default:
  75. throw new Error("Unsupported patch operation: " + patch.op);
  76. }
  77. }
  78. };
  79. for (var i = 0; i < patches.length; i++) {
  80. _loop(i);
  81. }
  82. return draft;
  83. }
  84. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  85. return typeof obj;
  86. } : function (obj) {
  87. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  88. };
  89. var defineProperty = function (obj, key, value) {
  90. if (key in obj) {
  91. Object.defineProperty(obj, key, {
  92. value: value,
  93. enumerable: true,
  94. configurable: true,
  95. writable: true
  96. });
  97. } else {
  98. obj[key] = value;
  99. }
  100. return obj;
  101. };
  102. var NOTHING = typeof Symbol !== "undefined" ? Symbol("immer-nothing") : defineProperty({}, "immer-nothing", true);
  103. var PROXY_STATE = typeof Symbol !== "undefined" ? Symbol("immer-proxy-state") : "__$immer_state";
  104. var RETURNED_AND_MODIFIED_ERROR = "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.";
  105. function verifyMinified() {}
  106. var inProduction = typeof process !== "undefined" && process.env.NODE_ENV === "production" || verifyMinified.name !== "verifyMinified";
  107. var autoFreeze = !inProduction;
  108. var useProxies = typeof Proxy !== "undefined";
  109. /**
  110. * Automatically freezes any state trees generated by immer.
  111. * This protects against accidental modifications of the state tree outside of an immer function.
  112. * This comes with a performance impact, so it is recommended to disable this option in production.
  113. * It is by default enabled.
  114. *
  115. * @returns {void}
  116. */
  117. function setAutoFreeze(enableAutoFreeze) {
  118. autoFreeze = enableAutoFreeze;
  119. }
  120. function setUseProxies(value) {
  121. useProxies = value;
  122. }
  123. function getUseProxies() {
  124. return useProxies;
  125. }
  126. function isProxy(value) {
  127. return !!value && !!value[PROXY_STATE];
  128. }
  129. function isProxyable(value) {
  130. if (!value) return false;
  131. if ((typeof value === "undefined" ? "undefined" : _typeof(value)) !== "object") return false;
  132. if (Array.isArray(value)) return true;
  133. var proto = Object.getPrototypeOf(value);
  134. return proto === null || proto === Object.prototype;
  135. }
  136. function freeze(value) {
  137. if (autoFreeze) {
  138. Object.freeze(value);
  139. }
  140. return value;
  141. }
  142. function original(value) {
  143. if (value && value[PROXY_STATE]) {
  144. return value[PROXY_STATE].base;
  145. }
  146. // otherwise return undefined
  147. }
  148. var assign = Object.assign || function assign(target, value) {
  149. for (var key in value) {
  150. if (has(value, key)) {
  151. target[key] = value[key];
  152. }
  153. }
  154. return target;
  155. };
  156. function shallowCopy(value) {
  157. if (Array.isArray(value)) return value.slice();
  158. var target = value.__proto__ === undefined ? Object.create(null) : {};
  159. return assign(target, value);
  160. }
  161. function each(value, cb) {
  162. if (Array.isArray(value)) {
  163. for (var i = 0; i < value.length; i++) {
  164. cb(i, value[i]);
  165. }
  166. } else {
  167. for (var key in value) {
  168. cb(key, value[key]);
  169. }
  170. }
  171. }
  172. function has(thing, prop) {
  173. return Object.prototype.hasOwnProperty.call(thing, prop);
  174. }
  175. // given a base object, returns it if unmodified, or return the changed cloned if modified
  176. function finalize(base, path, patches, inversePatches) {
  177. if (isProxy(base)) {
  178. var state = base[PROXY_STATE];
  179. if (state.modified === true) {
  180. if (state.finalized === true) return state.copy;
  181. state.finalized = true;
  182. var result = finalizeObject(useProxies ? state.copy : state.copy = shallowCopy(base), state, path, patches, inversePatches);
  183. generatePatches(state, path, patches, inversePatches, state.base, result);
  184. return result;
  185. } else {
  186. return state.base;
  187. }
  188. }
  189. finalizeNonProxiedObject(base);
  190. return base;
  191. }
  192. function finalizeObject(copy, state, path, patches, inversePatches) {
  193. var base = state.base;
  194. each(copy, function (prop, value) {
  195. if (value !== base[prop]) {
  196. // if there was an assignment on this property, we don't need to generate
  197. // patches for the subtree
  198. var _generatePatches = patches && !has(state.assigned, prop);
  199. copy[prop] = finalize(value, _generatePatches && path.concat(prop), _generatePatches && patches, inversePatches);
  200. }
  201. });
  202. return freeze(copy);
  203. }
  204. function finalizeNonProxiedObject(parent) {
  205. // If finalize is called on an object that was not a proxy, it means that it is an object that was not there in the original
  206. // tree and it could contain proxies at arbitrarily places. Let's find and finalize them as well
  207. if (!isProxyable(parent)) return;
  208. if (Object.isFrozen(parent)) return;
  209. each(parent, function (i, child) {
  210. if (isProxy(child)) {
  211. parent[i] = finalize(child);
  212. } else finalizeNonProxiedObject(child);
  213. });
  214. // always freeze completely new data
  215. freeze(parent);
  216. }
  217. function is(x, y) {
  218. // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
  219. if (x === y) {
  220. return x !== 0 || 1 / x === 1 / y;
  221. } else {
  222. return x !== x && y !== y;
  223. }
  224. }
  225. // @ts-check
  226. var proxies = null;
  227. var objectTraps = {
  228. get: get$1,
  229. has: function has$$1(target, prop) {
  230. return prop in source(target);
  231. },
  232. ownKeys: function ownKeys(target) {
  233. return Reflect.ownKeys(source(target));
  234. },
  235. set: set$1,
  236. deleteProperty: deleteProperty,
  237. getOwnPropertyDescriptor: getOwnPropertyDescriptor,
  238. defineProperty: defineProperty$1,
  239. setPrototypeOf: function setPrototypeOf() {
  240. throw new Error("Immer does not support `setPrototypeOf()`.");
  241. }
  242. };
  243. var arrayTraps = {};
  244. each(objectTraps, function (key, fn) {
  245. arrayTraps[key] = function () {
  246. arguments[0] = arguments[0][0];
  247. return fn.apply(this, arguments);
  248. };
  249. });
  250. arrayTraps.deleteProperty = function (state, prop) {
  251. if (isNaN(parseInt(prop))) throw new Error("Immer does not support deleting properties from arrays: " + prop);
  252. return objectTraps.deleteProperty.call(this, state[0], prop);
  253. };
  254. arrayTraps.set = function (state, prop, value) {
  255. if (prop !== "length" && isNaN(parseInt(prop))) throw new Error("Immer does not support setting non-numeric properties on arrays: " + prop);
  256. return objectTraps.set.call(this, state[0], prop, value);
  257. };
  258. function createState(parent, base) {
  259. return {
  260. modified: false, // this tree is modified (either this object or one of it's children)
  261. assigned: {}, // true: value was assigned to these props, false: was removed
  262. finalized: false,
  263. parent: parent,
  264. base: base,
  265. copy: undefined,
  266. proxies: {}
  267. };
  268. }
  269. function source(state) {
  270. return state.modified === true ? state.copy : state.base;
  271. }
  272. function get$1(state, prop) {
  273. if (prop === PROXY_STATE) return state;
  274. if (state.modified) {
  275. var value = state.copy[prop];
  276. if (value === state.base[prop] && isProxyable(value))
  277. // only create proxy if it is not yet a proxy, and not a new object
  278. // (new objects don't need proxying, they will be processed in finalize anyway)
  279. return state.copy[prop] = createProxy(state, value);
  280. return value;
  281. } else {
  282. if (has(state.proxies, prop)) return state.proxies[prop];
  283. var _value = state.base[prop];
  284. if (!isProxy(_value) && isProxyable(_value)) return state.proxies[prop] = createProxy(state, _value);
  285. return _value;
  286. }
  287. }
  288. function set$1(state, prop, value) {
  289. // TODO: optimize
  290. state.assigned[prop] = true;
  291. if (!state.modified) {
  292. if (prop in state.base && is(state.base[prop], value) || has(state.proxies, prop) && state.proxies[prop] === value) return true;
  293. markChanged(state);
  294. }
  295. state.copy[prop] = value;
  296. return true;
  297. }
  298. function deleteProperty(state, prop) {
  299. state.assigned[prop] = false;
  300. markChanged(state);
  301. delete state.copy[prop];
  302. return true;
  303. }
  304. function getOwnPropertyDescriptor(state, prop) {
  305. var owner = state.modified ? state.copy : has(state.proxies, prop) ? state.proxies : state.base;
  306. var descriptor = Reflect.getOwnPropertyDescriptor(owner, prop);
  307. if (descriptor && !(Array.isArray(owner) && prop === "length")) descriptor.configurable = true;
  308. return descriptor;
  309. }
  310. function defineProperty$1() {
  311. throw new Error("Immer does not support defining properties on draft objects.");
  312. }
  313. function markChanged(state) {
  314. if (!state.modified) {
  315. state.modified = true;
  316. state.copy = shallowCopy(state.base);
  317. // copy the proxies over the base-copy
  318. Object.assign(state.copy, state.proxies); // yup that works for arrays as well
  319. if (state.parent) markChanged(state.parent);
  320. }
  321. }
  322. // creates a proxy for plain objects / arrays
  323. function createProxy(parentState, base, key) {
  324. if (isProxy(base)) throw new Error("Immer bug. Plz report.");
  325. var state = createState(parentState, base, key);
  326. var proxy = Array.isArray(base) ? Proxy.revocable([state], arrayTraps) : Proxy.revocable(state, objectTraps);
  327. proxies.push(proxy);
  328. return proxy.proxy;
  329. }
  330. function produceProxy(baseState, producer, patchListener) {
  331. if (isProxy(baseState)) {
  332. // See #100, don't nest producers
  333. var returnValue = producer.call(baseState, baseState);
  334. return returnValue === undefined ? baseState : returnValue;
  335. }
  336. var previousProxies = proxies;
  337. proxies = [];
  338. var patches = patchListener && [];
  339. var inversePatches = patchListener && [];
  340. try {
  341. // create proxy for root
  342. var rootProxy = createProxy(undefined, baseState);
  343. // execute the thunk
  344. var _returnValue = producer.call(rootProxy, rootProxy);
  345. // and finalize the modified proxy
  346. var result = void 0;
  347. // check whether the draft was modified and/or a value was returned
  348. if (_returnValue !== undefined && _returnValue !== rootProxy) {
  349. // something was returned, and it wasn't the proxy itself
  350. if (rootProxy[PROXY_STATE].modified) throw new Error(RETURNED_AND_MODIFIED_ERROR);
  351. // See #117
  352. // Should we just throw when returning a proxy which is not the root, but a subset of the original state?
  353. // Looks like a wrongly modeled reducer
  354. result = finalize(_returnValue);
  355. if (patches) {
  356. patches.push({ op: "replace", path: [], value: result });
  357. inversePatches.push({ op: "replace", path: [], value: baseState });
  358. }
  359. } else {
  360. result = finalize(rootProxy, [], patches, inversePatches);
  361. }
  362. // revoke all proxies
  363. each(proxies, function (_, p) {
  364. return p.revoke();
  365. });
  366. patchListener && patchListener(patches, inversePatches);
  367. return result;
  368. } finally {
  369. proxies = previousProxies;
  370. }
  371. }
  372. // @ts-check
  373. var descriptors = {};
  374. var states = null;
  375. function createState$1(parent, proxy, base) {
  376. return {
  377. modified: false,
  378. assigned: {}, // true: value was assigned to these props, false: was removed
  379. hasCopy: false,
  380. parent: parent,
  381. base: base,
  382. proxy: proxy,
  383. copy: undefined,
  384. finished: false,
  385. finalizing: false,
  386. finalized: false
  387. };
  388. }
  389. function source$1(state) {
  390. return state.hasCopy ? state.copy : state.base;
  391. }
  392. function _get(state, prop) {
  393. assertUnfinished(state);
  394. var value = source$1(state)[prop];
  395. if (!state.finalizing && value === state.base[prop] && isProxyable(value)) {
  396. // only create a proxy if the value is proxyable, and the value was in the base state
  397. // if it wasn't in the base state, the object is already modified and we will process it in finalize
  398. prepareCopy(state);
  399. return state.copy[prop] = createProxy$1(state, value);
  400. }
  401. return value;
  402. }
  403. function _set(state, prop, value) {
  404. assertUnfinished(state);
  405. state.assigned[prop] = true; // optimization; skip this if there is no listener
  406. if (!state.modified) {
  407. if (is(source$1(state)[prop], value)) return;
  408. markChanged$1(state);
  409. prepareCopy(state);
  410. }
  411. state.copy[prop] = value;
  412. }
  413. function markChanged$1(state) {
  414. if (!state.modified) {
  415. state.modified = true;
  416. if (state.parent) markChanged$1(state.parent);
  417. }
  418. }
  419. function prepareCopy(state) {
  420. if (state.hasCopy) return;
  421. state.hasCopy = true;
  422. state.copy = shallowCopy(state.base);
  423. }
  424. // creates a proxy for plain objects / arrays
  425. function createProxy$1(parent, base) {
  426. var proxy = shallowCopy(base);
  427. each(base, function (i) {
  428. Object.defineProperty(proxy, "" + i, createPropertyProxy("" + i));
  429. });
  430. var state = createState$1(parent, proxy, base);
  431. createHiddenProperty(proxy, PROXY_STATE, state);
  432. states.push(state);
  433. return proxy;
  434. }
  435. function createPropertyProxy(prop) {
  436. return descriptors[prop] || (descriptors[prop] = {
  437. configurable: true,
  438. enumerable: true,
  439. get: function get$$1() {
  440. return _get(this[PROXY_STATE], prop);
  441. },
  442. set: function set$$1(value) {
  443. _set(this[PROXY_STATE], prop, value);
  444. }
  445. });
  446. }
  447. function assertUnfinished(state) {
  448. if (state.finished === 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(state.copy || state.base));
  449. }
  450. // this sounds very expensive, but actually it is not that expensive in practice
  451. // as it will only visit proxies, and only do key-based change detection for objects for
  452. // which it is not already know that they are changed (that is, only object for which no known key was changed)
  453. function markChangesSweep() {
  454. // intentionally we process the proxies in reverse order;
  455. // ideally we start by processing leafs in the tree, because if a child has changed, we don't have to check the parent anymore
  456. // reverse order of proxy creation approximates this
  457. for (var i = states.length - 1; i >= 0; i--) {
  458. var state = states[i];
  459. if (state.modified === false) {
  460. if (Array.isArray(state.base)) {
  461. if (hasArrayChanges(state)) markChanged$1(state);
  462. } else if (hasObjectChanges(state)) markChanged$1(state);
  463. }
  464. }
  465. }
  466. function markChangesRecursively(object) {
  467. if (!object || (typeof object === "undefined" ? "undefined" : _typeof(object)) !== "object") return;
  468. var state = object[PROXY_STATE];
  469. if (!state) return;
  470. var proxy = state.proxy,
  471. base = state.base;
  472. if (Array.isArray(object)) {
  473. if (hasArrayChanges(state)) {
  474. markChanged$1(state);
  475. state.assigned.length = true;
  476. if (proxy.length < base.length) for (var i = proxy.length; i < base.length; i++) {
  477. state.assigned[i] = false;
  478. } else for (var _i = base.length; _i < proxy.length; _i++) {
  479. state.assigned[_i] = true;
  480. }each(proxy, function (index, child) {
  481. if (!state.assigned[index]) markChangesRecursively(child);
  482. });
  483. }
  484. } else {
  485. var _diffKeys = diffKeys(base, proxy),
  486. added = _diffKeys.added,
  487. removed = _diffKeys.removed;
  488. if (added.length > 0 || removed.length > 0) markChanged$1(state);
  489. each(added, function (_, key) {
  490. state.assigned[key] = true;
  491. });
  492. each(removed, function (_, key) {
  493. state.assigned[key] = false;
  494. });
  495. each(proxy, function (key, child) {
  496. if (!state.assigned[key]) markChangesRecursively(child);
  497. });
  498. }
  499. }
  500. function diffKeys(from, to) {
  501. // TODO: optimize
  502. var a = Object.keys(from);
  503. var b = Object.keys(to);
  504. return {
  505. added: b.filter(function (key) {
  506. return a.indexOf(key) === -1;
  507. }),
  508. removed: a.filter(function (key) {
  509. return b.indexOf(key) === -1;
  510. })
  511. };
  512. }
  513. function hasObjectChanges(state) {
  514. var baseKeys = Object.keys(state.base);
  515. var keys = Object.keys(state.proxy);
  516. return !shallowEqual(baseKeys, keys);
  517. }
  518. function hasArrayChanges(state) {
  519. var proxy = state.proxy;
  520. if (proxy.length !== state.base.length) return true;
  521. // See #116
  522. // If we first shorten the length, our array interceptors will be removed.
  523. // If after that new items are added, result in the same original length,
  524. // those last items will have no intercepting property.
  525. // So if there is no own descriptor on the last position, we know that items were removed and added
  526. // N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check
  527. // the last one
  528. var descriptor = Object.getOwnPropertyDescriptor(proxy, proxy.length - 1);
  529. // descriptor can be null, but only for newly created sparse arrays, eg. new Array(10)
  530. if (descriptor && !descriptor.get) return true;
  531. // For all other cases, we don't have to compare, as they would have been picked up by the index setters
  532. return false;
  533. }
  534. function produceEs5(baseState, producer, patchListener) {
  535. if (isProxy(baseState)) {
  536. // See #100, don't nest producers
  537. var returnValue = producer.call(baseState, baseState);
  538. return returnValue === undefined ? baseState : returnValue;
  539. }
  540. var prevStates = states;
  541. states = [];
  542. var patches = patchListener && [];
  543. var inversePatches = patchListener && [];
  544. try {
  545. // create proxy for root
  546. var rootProxy = createProxy$1(undefined, baseState);
  547. // execute the thunk
  548. var _returnValue = producer.call(rootProxy, rootProxy);
  549. // and finalize the modified proxy
  550. each(states, function (_, state) {
  551. state.finalizing = true;
  552. });
  553. var result = void 0;
  554. // check whether the draft was modified and/or a value was returned
  555. if (_returnValue !== undefined && _returnValue !== rootProxy) {
  556. // something was returned, and it wasn't the proxy itself
  557. if (rootProxy[PROXY_STATE].modified) throw new Error(RETURNED_AND_MODIFIED_ERROR);
  558. result = finalize(_returnValue);
  559. if (patches) {
  560. patches.push({ op: "replace", path: [], value: result });
  561. inversePatches.push({ op: "replace", path: [], value: baseState });
  562. }
  563. } else {
  564. if (patchListener) markChangesRecursively(rootProxy);
  565. markChangesSweep(); // this one is more efficient if we don't need to know which attributes have changed
  566. result = finalize(rootProxy, [], patches, inversePatches);
  567. }
  568. // make sure all proxies become unusable
  569. each(states, function (_, state) {
  570. state.finished = true;
  571. });
  572. patchListener && patchListener(patches, inversePatches);
  573. return result;
  574. } finally {
  575. states = prevStates;
  576. }
  577. }
  578. function shallowEqual(objA, objB) {
  579. //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
  580. if (is(objA, objB)) return true;
  581. if ((typeof objA === "undefined" ? "undefined" : _typeof(objA)) !== "object" || objA === null || (typeof objB === "undefined" ? "undefined" : _typeof(objB)) !== "object" || objB === null) {
  582. return false;
  583. }
  584. var keysA = Object.keys(objA);
  585. var keysB = Object.keys(objB);
  586. if (keysA.length !== keysB.length) return false;
  587. for (var i = 0; i < keysA.length; i++) {
  588. if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
  589. return false;
  590. }
  591. }
  592. return true;
  593. }
  594. function createHiddenProperty(target, prop, value) {
  595. Object.defineProperty(target, prop, {
  596. value: value,
  597. enumerable: false,
  598. writable: true
  599. });
  600. }
  601. /**
  602. * produce takes a state, and runs a function against it.
  603. * That function can freely mutate the state, as it will create copies-on-write.
  604. * This means that the original state will stay unchanged, and once the function finishes, the modified state is returned
  605. *
  606. * @export
  607. * @param {any} baseState - the state to start with
  608. * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified
  609. * @param {Function} patchListener - optional function that will be called with all the patches produced here
  610. * @returns {any} a new state, or the base state if nothing was modified
  611. */
  612. function produce(baseState, producer, patchListener) {
  613. // prettier-ignore
  614. if (arguments.length < 1 || arguments.length > 3) throw new Error("produce expects 1 to 3 arguments, got " + arguments.length);
  615. // curried invocation
  616. if (typeof baseState === "function") {
  617. // prettier-ignore
  618. if (typeof producer === "function") throw new Error("if first argument is a function (curried invocation), the second argument to produce cannot be a function");
  619. var initialState = producer;
  620. var recipe = baseState;
  621. return function () {
  622. var args = arguments;
  623. var currentState = args[0] === undefined && initialState !== undefined ? initialState : args[0];
  624. return produce(currentState, function (draft) {
  625. args[0] = draft; // blegh!
  626. return recipe.apply(draft, args);
  627. });
  628. };
  629. }
  630. // prettier-ignore
  631. {
  632. if (typeof producer !== "function") throw new Error("if first argument is not a function, the second argument to produce should be a function");
  633. if (patchListener !== undefined && typeof patchListener !== "function") throw new Error("the third argument of a producer should not be set or a function");
  634. }
  635. // if state is a primitive, don't bother proxying at all
  636. if ((typeof baseState === "undefined" ? "undefined" : _typeof(baseState)) !== "object" || baseState === null) {
  637. var returnValue = producer(baseState);
  638. return returnValue === undefined ? baseState : normalizeResult(returnValue);
  639. }
  640. if (!isProxyable(baseState)) throw new Error("the first argument to an immer producer should be a primitive, plain object or array, got " + (typeof baseState === "undefined" ? "undefined" : _typeof(baseState)) + ": \"" + baseState + "\"");
  641. return normalizeResult(getUseProxies() ? produceProxy(baseState, producer, patchListener) : produceEs5(baseState, producer, patchListener));
  642. }
  643. function normalizeResult(result) {
  644. return result === NOTHING ? undefined : result;
  645. }
  646. var applyPatches$1 = produce(applyPatches);
  647. var nothing = NOTHING;
  648. exports.produce = produce;
  649. exports['default'] = produce;
  650. exports.applyPatches = applyPatches$1;
  651. exports.nothing = nothing;
  652. exports.setAutoFreeze = setAutoFreeze;
  653. exports.setUseProxies = setUseProxies;
  654. exports.original = original;
  655. //# sourceMappingURL=immer.js.map