EventuallyQueue.js 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
  3. var _sliceInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/slice");
  4. var _reverseInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/reverse");
  5. var _Promise = require("@babel/runtime-corejs3/core-js-stable/promise");
  6. var _Object$setPrototypeOf = require("@babel/runtime-corejs3/core-js-stable/object/set-prototype-of");
  7. var _typeof = require("@babel/runtime-corejs3/helpers/typeof");
  8. var _forEachInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/for-each");
  9. var _Object$getPrototypeOf = require("@babel/runtime-corejs3/core-js-stable/object/get-prototype-of");
  10. var _Object$create = require("@babel/runtime-corejs3/core-js-stable/object/create");
  11. var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
  12. var _Symbol = require("@babel/runtime-corejs3/core-js-stable/symbol");
  13. var _find = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find"));
  14. var _setInterval2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/set-interval"));
  15. var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/toConsumableArray"));
  16. var _findIndex = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find-index"));
  17. var _splice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/splice"));
  18. var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify"));
  19. var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/asyncToGenerator"));
  20. var _CoreManager = _interopRequireDefault(require("./CoreManager"));
  21. var _ParseObject = _interopRequireDefault(require("./ParseObject"));
  22. var _ParseQuery = _interopRequireDefault(require("./ParseQuery"));
  23. var _Storage = _interopRequireDefault(require("./Storage"));
  24. function _regeneratorRuntime() {
  25. "use strict";
  26. /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
  27. _regeneratorRuntime = function () {
  28. return exports;
  29. };
  30. var exports = {},
  31. Op = Object.prototype,
  32. hasOwn = Op.hasOwnProperty,
  33. $Symbol = "function" == typeof _Symbol ? _Symbol : {},
  34. iteratorSymbol = $Symbol.iterator || "@@iterator",
  35. asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
  36. toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  37. function define(obj, key, value) {
  38. return _Object$defineProperty(obj, key, {
  39. value: value,
  40. enumerable: !0,
  41. configurable: !0,
  42. writable: !0
  43. }), obj[key];
  44. }
  45. try {
  46. define({}, "");
  47. } catch (err) {
  48. define = function (obj, key, value) {
  49. return obj[key] = value;
  50. };
  51. }
  52. function wrap(innerFn, outerFn, self, tryLocsList) {
  53. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
  54. generator = _Object$create(protoGenerator.prototype),
  55. context = new Context(tryLocsList || []);
  56. return generator._invoke = function (innerFn, self, context) {
  57. var state = "suspendedStart";
  58. return function (method, arg) {
  59. if ("executing" === state) throw new Error("Generator is already running");
  60. if ("completed" === state) {
  61. if ("throw" === method) throw arg;
  62. return doneResult();
  63. }
  64. for (context.method = method, context.arg = arg;;) {
  65. var delegate = context.delegate;
  66. if (delegate) {
  67. var delegateResult = maybeInvokeDelegate(delegate, context);
  68. if (delegateResult) {
  69. if (delegateResult === ContinueSentinel) continue;
  70. return delegateResult;
  71. }
  72. }
  73. if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
  74. if ("suspendedStart" === state) throw state = "completed", context.arg;
  75. context.dispatchException(context.arg);
  76. } else "return" === context.method && context.abrupt("return", context.arg);
  77. state = "executing";
  78. var record = tryCatch(innerFn, self, context);
  79. if ("normal" === record.type) {
  80. if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
  81. return {
  82. value: record.arg,
  83. done: context.done
  84. };
  85. }
  86. "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
  87. }
  88. };
  89. }(innerFn, self, context), generator;
  90. }
  91. function tryCatch(fn, obj, arg) {
  92. try {
  93. return {
  94. type: "normal",
  95. arg: fn.call(obj, arg)
  96. };
  97. } catch (err) {
  98. return {
  99. type: "throw",
  100. arg: err
  101. };
  102. }
  103. }
  104. exports.wrap = wrap;
  105. var ContinueSentinel = {};
  106. function Generator() {}
  107. function GeneratorFunction() {}
  108. function GeneratorFunctionPrototype() {}
  109. var IteratorPrototype = {};
  110. define(IteratorPrototype, iteratorSymbol, function () {
  111. return this;
  112. });
  113. var getProto = _Object$getPrototypeOf,
  114. NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  115. NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
  116. var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = _Object$create(IteratorPrototype);
  117. function defineIteratorMethods(prototype) {
  118. var _context9;
  119. _forEachInstanceProperty(_context9 = ["next", "throw", "return"]).call(_context9, function (method) {
  120. define(prototype, method, function (arg) {
  121. return this._invoke(method, arg);
  122. });
  123. });
  124. }
  125. function AsyncIterator(generator, PromiseImpl) {
  126. function invoke(method, arg, resolve, reject) {
  127. var record = tryCatch(generator[method], generator, arg);
  128. if ("throw" !== record.type) {
  129. var result = record.arg,
  130. value = result.value;
  131. return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
  132. invoke("next", value, resolve, reject);
  133. }, function (err) {
  134. invoke("throw", err, resolve, reject);
  135. }) : PromiseImpl.resolve(value).then(function (unwrapped) {
  136. result.value = unwrapped, resolve(result);
  137. }, function (error) {
  138. return invoke("throw", error, resolve, reject);
  139. });
  140. }
  141. reject(record.arg);
  142. }
  143. var previousPromise;
  144. this._invoke = function (method, arg) {
  145. function callInvokeWithMethodAndArg() {
  146. return new PromiseImpl(function (resolve, reject) {
  147. invoke(method, arg, resolve, reject);
  148. });
  149. }
  150. return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
  151. };
  152. }
  153. function maybeInvokeDelegate(delegate, context) {
  154. var method = delegate.iterator[context.method];
  155. if (undefined === method) {
  156. if (context.delegate = null, "throw" === context.method) {
  157. if (delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel;
  158. context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method");
  159. }
  160. return ContinueSentinel;
  161. }
  162. var record = tryCatch(method, delegate.iterator, context.arg);
  163. if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
  164. var info = record.arg;
  165. return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
  166. }
  167. function pushTryEntry(locs) {
  168. var entry = {
  169. tryLoc: locs[0]
  170. };
  171. 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
  172. }
  173. function resetTryEntry(entry) {
  174. var record = entry.completion || {};
  175. record.type = "normal", delete record.arg, entry.completion = record;
  176. }
  177. function Context(tryLocsList) {
  178. this.tryEntries = [{
  179. tryLoc: "root"
  180. }], _forEachInstanceProperty(tryLocsList).call(tryLocsList, pushTryEntry, this), this.reset(!0);
  181. }
  182. function values(iterable) {
  183. if (iterable) {
  184. var iteratorMethod = iterable[iteratorSymbol];
  185. if (iteratorMethod) return iteratorMethod.call(iterable);
  186. if ("function" == typeof iterable.next) return iterable;
  187. if (!isNaN(iterable.length)) {
  188. var i = -1,
  189. next = function next() {
  190. for (; ++i < iterable.length;) {
  191. if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
  192. }
  193. return next.value = undefined, next.done = !0, next;
  194. };
  195. return next.next = next;
  196. }
  197. }
  198. return {
  199. next: doneResult
  200. };
  201. }
  202. function doneResult() {
  203. return {
  204. value: undefined,
  205. done: !0
  206. };
  207. }
  208. return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
  209. var ctor = "function" == typeof genFun && genFun.constructor;
  210. return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
  211. }, exports.mark = function (genFun) {
  212. return _Object$setPrototypeOf ? _Object$setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = _Object$create(Gp), genFun;
  213. }, exports.awrap = function (arg) {
  214. return {
  215. __await: arg
  216. };
  217. }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
  218. return this;
  219. }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
  220. void 0 === PromiseImpl && (PromiseImpl = _Promise);
  221. var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
  222. return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
  223. return result.done ? result.value : iter.next();
  224. });
  225. }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
  226. return this;
  227. }), define(Gp, "toString", function () {
  228. return "[object Generator]";
  229. }), exports.keys = function (object) {
  230. var keys = [];
  231. for (var key in object) {
  232. keys.push(key);
  233. }
  234. return _reverseInstanceProperty(keys).call(keys), function next() {
  235. for (; keys.length;) {
  236. var key = keys.pop();
  237. if (key in object) return next.value = key, next.done = !1, next;
  238. }
  239. return next.done = !0, next;
  240. };
  241. }, exports.values = values, Context.prototype = {
  242. constructor: Context,
  243. reset: function (skipTempReset) {
  244. var _context10;
  245. if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, _forEachInstanceProperty(_context10 = this.tryEntries).call(_context10, resetTryEntry), !skipTempReset) for (var name in this) {
  246. "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+_sliceInstanceProperty(name).call(name, 1)) && (this[name] = undefined);
  247. }
  248. },
  249. stop: function () {
  250. this.done = !0;
  251. var rootRecord = this.tryEntries[0].completion;
  252. if ("throw" === rootRecord.type) throw rootRecord.arg;
  253. return this.rval;
  254. },
  255. dispatchException: function (exception) {
  256. if (this.done) throw exception;
  257. var context = this;
  258. function handle(loc, caught) {
  259. return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
  260. }
  261. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  262. var entry = this.tryEntries[i],
  263. record = entry.completion;
  264. if ("root" === entry.tryLoc) return handle("end");
  265. if (entry.tryLoc <= this.prev) {
  266. var hasCatch = hasOwn.call(entry, "catchLoc"),
  267. hasFinally = hasOwn.call(entry, "finallyLoc");
  268. if (hasCatch && hasFinally) {
  269. if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
  270. if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
  271. } else if (hasCatch) {
  272. if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
  273. } else {
  274. if (!hasFinally) throw new Error("try statement without catch or finally");
  275. if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
  276. }
  277. }
  278. }
  279. },
  280. abrupt: function (type, arg) {
  281. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  282. var entry = this.tryEntries[i];
  283. if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
  284. var finallyEntry = entry;
  285. break;
  286. }
  287. }
  288. finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
  289. var record = finallyEntry ? finallyEntry.completion : {};
  290. return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
  291. },
  292. complete: function (record, afterLoc) {
  293. if ("throw" === record.type) throw record.arg;
  294. return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
  295. },
  296. finish: function (finallyLoc) {
  297. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  298. var entry = this.tryEntries[i];
  299. if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
  300. }
  301. },
  302. catch: function (tryLoc) {
  303. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  304. var entry = this.tryEntries[i];
  305. if (entry.tryLoc === tryLoc) {
  306. var record = entry.completion;
  307. if ("throw" === record.type) {
  308. var thrown = record.arg;
  309. resetTryEntry(entry);
  310. }
  311. return thrown;
  312. }
  313. }
  314. throw new Error("illegal catch attempt");
  315. },
  316. delegateYield: function (iterable, resultName, nextLoc) {
  317. return this.delegate = {
  318. iterator: values(iterable),
  319. resultName: resultName,
  320. nextLoc: nextLoc
  321. }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
  322. }
  323. }, exports;
  324. }
  325. var QUEUE_KEY = 'Parse/Eventually/Queue';
  326. var queueCache = [];
  327. var dirtyCache = true;
  328. var polling = undefined;
  329. /**
  330. * Provides utility functions to queue objects that will be
  331. * saved to the server at a later date.
  332. *
  333. * @class Parse.EventuallyQueue
  334. * @static
  335. */
  336. var EventuallyQueue = {
  337. /**
  338. * Add object to queue with save operation.
  339. *
  340. * @function save
  341. * @name Parse.EventuallyQueue.save
  342. * @param {ParseObject} object Parse.Object to be saved eventually
  343. * @param {object} [serverOptions] See {@link https://parseplatform.org/Parse-SDK-JS/api/master/Parse.Object.html#save Parse.Object.save} options.
  344. * @returns {Promise} A promise that is fulfilled if object is added to queue.
  345. * @static
  346. * @see Parse.Object#saveEventually
  347. */
  348. save: function (object
  349. /*: ParseObject*/
  350. )
  351. /*: Promise*/
  352. {
  353. var serverOptions
  354. /*: SaveOptions*/
  355. = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  356. return this.enqueue('save', object, serverOptions);
  357. },
  358. /**
  359. * Add object to queue with save operation.
  360. *
  361. * @function destroy
  362. * @name Parse.EventuallyQueue.destroy
  363. * @param {ParseObject} object Parse.Object to be destroyed eventually
  364. * @param {object} [serverOptions] See {@link https://parseplatform.org/Parse-SDK-JS/api/master/Parse.Object.html#destroy Parse.Object.destroy} options
  365. * @returns {Promise} A promise that is fulfilled if object is added to queue.
  366. * @static
  367. * @see Parse.Object#destroyEventually
  368. */
  369. destroy: function (object
  370. /*: ParseObject*/
  371. )
  372. /*: Promise*/
  373. {
  374. var serverOptions
  375. /*: RequestOptions*/
  376. = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  377. return this.enqueue('destroy', object, serverOptions);
  378. },
  379. /**
  380. * Generate unique identifier to avoid duplicates and maintain previous state.
  381. *
  382. * @param {string} action save / destroy
  383. * @param {object} object Parse.Object to be queued
  384. * @returns {string}
  385. * @static
  386. * @ignore
  387. */
  388. generateQueueId: function (action
  389. /*: string*/
  390. , object
  391. /*: ParseObject*/
  392. )
  393. /*: string*/
  394. {
  395. object._getId();
  396. var className = object.className,
  397. id = object.id,
  398. _localId = object._localId;
  399. var uniqueId = object.get('hash') || _localId;
  400. return [action, className, id, uniqueId].join('_');
  401. },
  402. /**
  403. * Build queue object and add to queue.
  404. *
  405. * @param {string} action save / destroy
  406. * @param {object} object Parse.Object to be queued
  407. * @param {object} [serverOptions]
  408. * @returns {Promise} A promise that is fulfilled if object is added to queue.
  409. * @static
  410. * @ignore
  411. */
  412. enqueue: function (action
  413. /*: string*/
  414. , object
  415. /*: ParseObject*/
  416. , serverOptions
  417. /*: SaveOptions | RequestOptions*/
  418. )
  419. /*: Promise*/
  420. {
  421. var _this = this;
  422. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
  423. var queueData, queueId, index, prop;
  424. return _regeneratorRuntime().wrap(function _callee$(_context) {
  425. while (1) {
  426. switch (_context.prev = _context.next) {
  427. case 0:
  428. _context.next = 2;
  429. return _this.getQueue();
  430. case 2:
  431. queueData = _context.sent;
  432. queueId = _this.generateQueueId(action, object);
  433. index = _this.queueItemExists(queueData, queueId);
  434. if (index > -1) {
  435. // Add cached values to new object if they don't exist
  436. for (prop in queueData[index].object) {
  437. if (typeof object.get(prop) === 'undefined') {
  438. object.set(prop, queueData[index].object[prop]);
  439. }
  440. }
  441. } else {
  442. index = queueData.length;
  443. }
  444. queueData[index] = {
  445. queueId: queueId,
  446. action: action,
  447. object: object.toJSON(),
  448. serverOptions: serverOptions,
  449. id: object.id,
  450. className: object.className,
  451. hash: object.get('hash'),
  452. createdAt: new Date()
  453. };
  454. return _context.abrupt("return", _this.setQueue(queueData));
  455. case 8:
  456. case "end":
  457. return _context.stop();
  458. }
  459. }
  460. }, _callee);
  461. }))();
  462. },
  463. store: function store(data) {
  464. return _Storage.default.setItemAsync(QUEUE_KEY, (0, _stringify.default)(data));
  465. },
  466. load: function load() {
  467. return _Storage.default.getItemAsync(QUEUE_KEY);
  468. },
  469. /**
  470. * Sets the in-memory queue from local storage and returns.
  471. *
  472. * @function getQueue
  473. * @name Parse.EventuallyQueue.getQueue
  474. * @returns {Promise<Array>}
  475. * @static
  476. */
  477. getQueue: function getQueue()
  478. /*: Promise<Array>*/
  479. {
  480. var _this2 = this;
  481. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
  482. return _regeneratorRuntime().wrap(function _callee2$(_context2) {
  483. while (1) {
  484. switch (_context2.prev = _context2.next) {
  485. case 0:
  486. if (!dirtyCache) {
  487. _context2.next = 10;
  488. break;
  489. }
  490. _context2.t0 = JSON;
  491. _context2.next = 4;
  492. return _this2.load();
  493. case 4:
  494. _context2.t1 = _context2.sent;
  495. if (_context2.t1) {
  496. _context2.next = 7;
  497. break;
  498. }
  499. _context2.t1 = '[]';
  500. case 7:
  501. _context2.t2 = _context2.t1;
  502. queueCache = _context2.t0.parse.call(_context2.t0, _context2.t2);
  503. dirtyCache = false;
  504. case 10:
  505. return _context2.abrupt("return", queueCache);
  506. case 11:
  507. case "end":
  508. return _context2.stop();
  509. }
  510. }
  511. }, _callee2);
  512. }))();
  513. },
  514. /**
  515. * Saves the queue to local storage
  516. *
  517. * @param {Queue} queue Queue containing Parse.Object data.
  518. * @returns {Promise} A promise that is fulfilled when queue is stored.
  519. * @static
  520. * @ignore
  521. */
  522. setQueue: function setQueue(queue
  523. /*: Queue*/
  524. )
  525. /*: Promise<void>*/
  526. {
  527. queueCache = queue;
  528. return this.store(queueCache);
  529. },
  530. /**
  531. * Removes Parse.Object data from queue.
  532. *
  533. * @param {string} queueId Unique identifier for Parse.Object data.
  534. * @returns {Promise} A promise that is fulfilled when queue is stored.
  535. * @static
  536. * @ignore
  537. */
  538. remove: function remove(queueId
  539. /*: string*/
  540. )
  541. /*: Promise<void>*/
  542. {
  543. var _this3 = this;
  544. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
  545. var queueData, index;
  546. return _regeneratorRuntime().wrap(function _callee3$(_context3) {
  547. while (1) {
  548. switch (_context3.prev = _context3.next) {
  549. case 0:
  550. _context3.next = 2;
  551. return _this3.getQueue();
  552. case 2:
  553. queueData = _context3.sent;
  554. index = _this3.queueItemExists(queueData, queueId);
  555. if (!(index > -1)) {
  556. _context3.next = 8;
  557. break;
  558. }
  559. (0, _splice.default)(queueData).call(queueData, index, 1);
  560. _context3.next = 8;
  561. return _this3.setQueue(queueData);
  562. case 8:
  563. case "end":
  564. return _context3.stop();
  565. }
  566. }
  567. }, _callee3);
  568. }))();
  569. },
  570. /**
  571. * Removes all objects from queue.
  572. *
  573. * @function clear
  574. * @name Parse.EventuallyQueue.clear
  575. * @returns {Promise} A promise that is fulfilled when queue is cleared.
  576. * @static
  577. */
  578. clear: function clear()
  579. /*: Promise*/
  580. {
  581. queueCache = [];
  582. return this.store([]);
  583. },
  584. /**
  585. * Return the index of a queueId in the queue. Returns -1 if not found.
  586. *
  587. * @param {Queue} queue Queue containing Parse.Object data.
  588. * @param {string} queueId Unique identifier for Parse.Object data.
  589. * @returns {number}
  590. * @static
  591. * @ignore
  592. */
  593. queueItemExists: function queueItemExists(queue
  594. /*: Queue*/
  595. , queueId
  596. /*: string*/
  597. )
  598. /*: number*/
  599. {
  600. return (0, _findIndex.default)(queue).call(queue, function (data) {
  601. return data.queueId === queueId;
  602. });
  603. },
  604. /**
  605. * Return the number of objects in the queue.
  606. *
  607. * @function length
  608. * @name Parse.EventuallyQueue.length
  609. * @returns {number}
  610. * @static
  611. */
  612. length: function length()
  613. /*: number*/
  614. {
  615. var _this4 = this;
  616. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
  617. var queueData;
  618. return _regeneratorRuntime().wrap(function _callee4$(_context4) {
  619. while (1) {
  620. switch (_context4.prev = _context4.next) {
  621. case 0:
  622. _context4.next = 2;
  623. return _this4.getQueue();
  624. case 2:
  625. queueData = _context4.sent;
  626. return _context4.abrupt("return", queueData.length);
  627. case 4:
  628. case "end":
  629. return _context4.stop();
  630. }
  631. }
  632. }, _callee4);
  633. }))();
  634. },
  635. /**
  636. * Sends the queue to the server.
  637. *
  638. * @function sendQueue
  639. * @name Parse.EventuallyQueue.sendQueue
  640. * @returns {Promise<boolean>} Returns true if queue was sent successfully.
  641. * @static
  642. */
  643. sendQueue: function sendQueue()
  644. /*: Promise<boolean>*/
  645. {
  646. var _this5 = this;
  647. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
  648. var queue, queueData, i, queueObject, id, hash, className, ObjectType;
  649. return _regeneratorRuntime().wrap(function _callee5$(_context5) {
  650. while (1) {
  651. switch (_context5.prev = _context5.next) {
  652. case 0:
  653. _context5.next = 2;
  654. return _this5.getQueue();
  655. case 2:
  656. queue = _context5.sent;
  657. queueData = (0, _toConsumableArray2.default)(queue);
  658. if (!(queueData.length === 0)) {
  659. _context5.next = 6;
  660. break;
  661. }
  662. return _context5.abrupt("return", false);
  663. case 6:
  664. i = 0;
  665. case 7:
  666. if (!(i < queueData.length)) {
  667. _context5.next = 26;
  668. break;
  669. }
  670. queueObject = queueData[i];
  671. id = queueObject.id, hash = queueObject.hash, className = queueObject.className;
  672. ObjectType = _ParseObject.default.extend(className);
  673. if (!id) {
  674. _context5.next = 16;
  675. break;
  676. }
  677. _context5.next = 14;
  678. return _this5.process.byId(ObjectType, queueObject);
  679. case 14:
  680. _context5.next = 23;
  681. break;
  682. case 16:
  683. if (!hash) {
  684. _context5.next = 21;
  685. break;
  686. }
  687. _context5.next = 19;
  688. return _this5.process.byHash(ObjectType, queueObject);
  689. case 19:
  690. _context5.next = 23;
  691. break;
  692. case 21:
  693. _context5.next = 23;
  694. return _this5.process.create(ObjectType, queueObject);
  695. case 23:
  696. i += 1;
  697. _context5.next = 7;
  698. break;
  699. case 26:
  700. return _context5.abrupt("return", true);
  701. case 27:
  702. case "end":
  703. return _context5.stop();
  704. }
  705. }
  706. }, _callee5);
  707. }))();
  708. },
  709. /**
  710. * Build queue object and add to queue.
  711. *
  712. * @param {ParseObject} object Parse.Object to be processed
  713. * @param {QueueObject} queueObject Parse.Object data from the queue
  714. * @returns {Promise} A promise that is fulfilled when operation is performed.
  715. * @static
  716. * @ignore
  717. */
  718. sendQueueCallback: function sendQueueCallback(object
  719. /*: ParseObject*/
  720. , queueObject
  721. /*: QueueObject*/
  722. )
  723. /*: Promise<void>*/
  724. {
  725. var _this6 = this;
  726. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
  727. return _regeneratorRuntime().wrap(function _callee6$(_context6) {
  728. while (1) {
  729. switch (_context6.prev = _context6.next) {
  730. case 0:
  731. if (object) {
  732. _context6.next = 2;
  733. break;
  734. }
  735. return _context6.abrupt("return", _this6.remove(queueObject.queueId));
  736. case 2:
  737. _context6.t0 = queueObject.action;
  738. _context6.next = _context6.t0 === 'save' ? 5 : _context6.t0 === 'destroy' ? 20 : 33;
  739. break;
  740. case 5:
  741. if (!(typeof object.updatedAt !== 'undefined' && object.updatedAt > new Date(queueObject.object.createdAt))) {
  742. _context6.next = 7;
  743. break;
  744. }
  745. return _context6.abrupt("return", _this6.remove(queueObject.queueId));
  746. case 7:
  747. _context6.prev = 7;
  748. _context6.next = 10;
  749. return object.save(queueObject.object, queueObject.serverOptions);
  750. case 10:
  751. _context6.next = 12;
  752. return _this6.remove(queueObject.queueId);
  753. case 12:
  754. _context6.next = 19;
  755. break;
  756. case 14:
  757. _context6.prev = 14;
  758. _context6.t1 = _context6["catch"](7);
  759. if (!(_context6.t1.message !== 'XMLHttpRequest failed: "Unable to connect to the Parse API"')) {
  760. _context6.next = 19;
  761. break;
  762. }
  763. _context6.next = 19;
  764. return _this6.remove(queueObject.queueId);
  765. case 19:
  766. return _context6.abrupt("break", 33);
  767. case 20:
  768. _context6.prev = 20;
  769. _context6.next = 23;
  770. return object.destroy(queueObject.serverOptions);
  771. case 23:
  772. _context6.next = 25;
  773. return _this6.remove(queueObject.queueId);
  774. case 25:
  775. _context6.next = 32;
  776. break;
  777. case 27:
  778. _context6.prev = 27;
  779. _context6.t2 = _context6["catch"](20);
  780. if (!(_context6.t2.message !== 'XMLHttpRequest failed: "Unable to connect to the Parse API"')) {
  781. _context6.next = 32;
  782. break;
  783. }
  784. _context6.next = 32;
  785. return _this6.remove(queueObject.queueId);
  786. case 32:
  787. return _context6.abrupt("break", 33);
  788. case 33:
  789. case "end":
  790. return _context6.stop();
  791. }
  792. }
  793. }, _callee6, null, [[7, 14], [20, 27]]);
  794. }))();
  795. },
  796. /**
  797. * Start polling server for network connection.
  798. * Will send queue if connection is established.
  799. *
  800. * @function poll
  801. * @name Parse.EventuallyQueue.poll
  802. * @param [ms] Milliseconds to ping the server. Default 2000ms
  803. * @static
  804. */
  805. poll: function poll() {
  806. var _this7 = this;
  807. var ms
  808. /*: number*/
  809. = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2000;
  810. if (polling) {
  811. return;
  812. }
  813. polling = (0, _setInterval2.default)(function () {
  814. var RESTController = _CoreManager.default.getRESTController();
  815. RESTController.request('GET', 'health').then(function (_ref) {
  816. var status = _ref.status;
  817. if (status === 'ok') {
  818. _this7.stopPoll();
  819. return _this7.sendQueue();
  820. }
  821. }).catch(function (e) {
  822. return e;
  823. });
  824. }, ms);
  825. },
  826. /**
  827. * Turns off polling.
  828. *
  829. * @function stopPoll
  830. * @name Parse.EventuallyQueue.stopPoll
  831. * @static
  832. */
  833. stopPoll: function stopPoll() {
  834. clearInterval(polling);
  835. polling = undefined;
  836. },
  837. /**
  838. * Return true if pinging the server.
  839. *
  840. * @function isPolling
  841. * @name Parse.EventuallyQueue.isPolling
  842. * @returns {boolean}
  843. * @static
  844. */
  845. isPolling: function isPolling()
  846. /*: boolean*/
  847. {
  848. return !!polling;
  849. },
  850. _setPolling: function _setPolling(flag
  851. /*: boolean*/
  852. ) {
  853. polling = flag;
  854. },
  855. process: {
  856. create: function create(ObjectType, queueObject) {
  857. var object = new ObjectType();
  858. return EventuallyQueue.sendQueueCallback(object, queueObject);
  859. },
  860. byId: function byId(ObjectType, queueObject) {
  861. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
  862. var sessionToken, query, results;
  863. return _regeneratorRuntime().wrap(function _callee7$(_context7) {
  864. while (1) {
  865. switch (_context7.prev = _context7.next) {
  866. case 0:
  867. sessionToken = queueObject.serverOptions.sessionToken;
  868. query = new _ParseQuery.default(ObjectType);
  869. query.equalTo('objectId', queueObject.id);
  870. _context7.next = 5;
  871. return (0, _find.default)(query).call(query, {
  872. sessionToken: sessionToken
  873. });
  874. case 5:
  875. results = _context7.sent;
  876. return _context7.abrupt("return", EventuallyQueue.sendQueueCallback(results[0], queueObject));
  877. case 7:
  878. case "end":
  879. return _context7.stop();
  880. }
  881. }
  882. }, _callee7);
  883. }))();
  884. },
  885. byHash: function byHash(ObjectType, queueObject) {
  886. return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
  887. var sessionToken, query, results;
  888. return _regeneratorRuntime().wrap(function _callee8$(_context8) {
  889. while (1) {
  890. switch (_context8.prev = _context8.next) {
  891. case 0:
  892. sessionToken = queueObject.serverOptions.sessionToken;
  893. query = new _ParseQuery.default(ObjectType);
  894. query.equalTo('hash', queueObject.hash);
  895. _context8.next = 5;
  896. return (0, _find.default)(query).call(query, {
  897. sessionToken: sessionToken
  898. });
  899. case 5:
  900. results = _context8.sent;
  901. if (!(results.length > 0)) {
  902. _context8.next = 8;
  903. break;
  904. }
  905. return _context8.abrupt("return", EventuallyQueue.sendQueueCallback(results[0], queueObject));
  906. case 8:
  907. return _context8.abrupt("return", EventuallyQueue.process.create(ObjectType, queueObject));
  908. case 9:
  909. case "end":
  910. return _context8.stop();
  911. }
  912. }
  913. }, _callee8);
  914. }))();
  915. }
  916. }
  917. };
  918. module.exports = EventuallyQueue;