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

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