ObjectStateMutations.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.commitServerChanges = commitServerChanges;
  6. exports.defaultState = defaultState;
  7. exports.estimateAttribute = estimateAttribute;
  8. exports.estimateAttributes = estimateAttributes;
  9. exports.mergeFirstPendingState = mergeFirstPendingState;
  10. exports.popPendingState = popPendingState;
  11. exports.pushPendingState = pushPendingState;
  12. exports.setPendingOp = setPendingOp;
  13. exports.setServerData = setServerData;
  14. var _encode = _interopRequireDefault(require("./encode"));
  15. var _CoreManager = _interopRequireDefault(require("./CoreManager"));
  16. var _ParseFile = _interopRequireDefault(require("./ParseFile"));
  17. var _ParseRelation = _interopRequireDefault(require("./ParseRelation"));
  18. var _TaskQueue = _interopRequireDefault(require("./TaskQueue"));
  19. var _ParseOp = require("./ParseOp");
  20. function _interopRequireDefault(e) {
  21. return e && e.__esModule ? e : {
  22. default: e
  23. };
  24. }
  25. function defaultState() {
  26. return {
  27. serverData: {},
  28. pendingOps: [{}],
  29. objectCache: {},
  30. tasks: new _TaskQueue.default(),
  31. existed: false
  32. };
  33. }
  34. function setServerData(serverData, attributes) {
  35. for (const attr in attributes) {
  36. if (typeof attributes[attr] !== 'undefined') {
  37. serverData[attr] = attributes[attr];
  38. } else {
  39. delete serverData[attr];
  40. }
  41. }
  42. }
  43. function setPendingOp(pendingOps, attr, op) {
  44. const last = pendingOps.length - 1;
  45. if (op) {
  46. pendingOps[last][attr] = op;
  47. } else {
  48. delete pendingOps[last][attr];
  49. }
  50. }
  51. function pushPendingState(pendingOps) {
  52. pendingOps.push({});
  53. }
  54. function popPendingState(pendingOps) {
  55. const first = pendingOps.shift();
  56. if (!pendingOps.length) {
  57. pendingOps[0] = {};
  58. }
  59. return first;
  60. }
  61. function mergeFirstPendingState(pendingOps) {
  62. const first = popPendingState(pendingOps);
  63. const next = pendingOps[0];
  64. for (const attr in first) {
  65. if (next[attr] && first[attr]) {
  66. const merged = next[attr].mergeWith(first[attr]);
  67. if (merged) {
  68. next[attr] = merged;
  69. }
  70. } else {
  71. next[attr] = first[attr];
  72. }
  73. }
  74. }
  75. function estimateAttribute(serverData, pendingOps, object, attr) {
  76. let value = serverData[attr];
  77. for (let i = 0; i < pendingOps.length; i++) {
  78. if (pendingOps[i][attr]) {
  79. if (pendingOps[i][attr] instanceof _ParseOp.RelationOp) {
  80. if (object.id) {
  81. value = pendingOps[i][attr].applyTo(value, object, attr);
  82. }
  83. } else {
  84. value = pendingOps[i][attr].applyTo(value);
  85. }
  86. }
  87. }
  88. return value;
  89. }
  90. function estimateAttributes(serverData, pendingOps, object) {
  91. const data = {};
  92. for (var attr in serverData) {
  93. data[attr] = serverData[attr];
  94. }
  95. for (let i = 0; i < pendingOps.length; i++) {
  96. for (attr in pendingOps[i]) {
  97. if (pendingOps[i][attr] instanceof _ParseOp.RelationOp) {
  98. if (object.id) {
  99. data[attr] = pendingOps[i][attr].applyTo(data[attr], object, attr);
  100. }
  101. } else {
  102. if (attr.includes('.')) {
  103. // similar to nestedSet function
  104. const fields = attr.split('.');
  105. const last = fields[fields.length - 1];
  106. let object = data;
  107. for (let i = 0; i < fields.length - 1; i++) {
  108. const key = fields[i];
  109. if (!(key in object)) {
  110. const nextKey = fields[i + 1];
  111. if (!isNaN(nextKey)) {
  112. object[key] = [];
  113. } else {
  114. object[key] = {};
  115. }
  116. } else {
  117. if (Array.isArray(object[key])) {
  118. object[key] = [...object[key]];
  119. } else {
  120. object[key] = {
  121. ...object[key]
  122. };
  123. }
  124. }
  125. object = object[key];
  126. }
  127. object[last] = pendingOps[i][attr].applyTo(object[last]);
  128. } else {
  129. data[attr] = pendingOps[i][attr].applyTo(data[attr]);
  130. }
  131. }
  132. }
  133. }
  134. return data;
  135. }
  136. /**
  137. * Allows setting properties/variables deep in an object.
  138. * Converts a.b into { a: { b: value } } for dot notation on Objects
  139. * Converts a.0.b into { a: [{ b: value }] } for dot notation on Arrays
  140. *
  141. * @param obj The object to assign the value to
  142. * @param key The key to assign. If it's in a deeper path, then use dot notation (`prop1.prop2.prop3`)
  143. * Note that intermediate object(s) in the nested path are automatically created if they don't exist.
  144. * @param value The value to assign. If it's an `undefined` then the key is deleted.
  145. */
  146. function nestedSet(obj, key, value) {
  147. const paths = key.split('.');
  148. for (let i = 0; i < paths.length - 1; i++) {
  149. const path = paths[i];
  150. if (!(path in obj)) {
  151. const nextPath = paths[i + 1];
  152. if (!isNaN(nextPath)) {
  153. obj[path] = [];
  154. } else {
  155. obj[path] = {};
  156. }
  157. }
  158. obj = obj[path];
  159. }
  160. if (typeof value === 'undefined') {
  161. delete obj[paths[paths.length - 1]];
  162. } else {
  163. obj[paths[paths.length - 1]] = value;
  164. }
  165. }
  166. function commitServerChanges(serverData, objectCache, changes) {
  167. const ParseObject = _CoreManager.default.getParseObject();
  168. for (const attr in changes) {
  169. const val = changes[attr];
  170. nestedSet(serverData, attr, val);
  171. if (val && typeof val === 'object' && !(val instanceof ParseObject) && !(val instanceof _ParseFile.default) && !(val instanceof _ParseRelation.default)) {
  172. const json = (0, _encode.default)(val, false, true);
  173. objectCache[attr] = JSON.stringify(json);
  174. }
  175. }
  176. }