LiveQueryClient.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. "use strict";
  2. var _Reflect$construct = require("@babel/runtime-corejs3/core-js-stable/reflect/construct");
  3. var _sliceInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/slice");
  4. var _Array$from = require("@babel/runtime-corejs3/core-js-stable/array/from");
  5. var _Symbol = require("@babel/runtime-corejs3/core-js-stable/symbol");
  6. var _getIteratorMethod = require("@babel/runtime-corejs3/core-js/get-iterator-method");
  7. var _Array$isArray = require("@babel/runtime-corejs3/core-js-stable/array/is-array");
  8. var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
  9. var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
  10. _Object$defineProperty(exports, "__esModule", {
  11. value: true
  12. });
  13. exports.default = void 0;
  14. var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of"));
  15. var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/map"));
  16. var _keys = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/keys"));
  17. var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify"));
  18. var _forEach = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/for-each"));
  19. var _values = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/values"));
  20. var _setTimeout2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/set-timeout"));
  21. var _bind = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/bind"));
  22. var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof"));
  23. var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
  24. var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
  25. var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/assertThisInitialized"));
  26. var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/inherits"));
  27. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/possibleConstructorReturn"));
  28. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/getPrototypeOf"));
  29. var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
  30. var _CoreManager = _interopRequireDefault(require("./CoreManager"));
  31. var _EventEmitter2 = _interopRequireDefault(require("./EventEmitter"));
  32. var _ParseObject = _interopRequireDefault(require("./ParseObject"));
  33. var _LiveQuerySubscription = _interopRequireDefault(require("./LiveQuerySubscription"));
  34. var _promiseUtils = require("./promiseUtils");
  35. function _createForOfIteratorHelper(o, allowArrayLike) {
  36. var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"];
  37. if (!it) {
  38. if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
  39. if (it) o = it;
  40. var i = 0;
  41. var F = function () {};
  42. return {
  43. s: F,
  44. n: function () {
  45. if (i >= o.length) return {
  46. done: true
  47. };
  48. return {
  49. done: false,
  50. value: o[i++]
  51. };
  52. },
  53. e: function (_e) {
  54. throw _e;
  55. },
  56. f: F
  57. };
  58. }
  59. throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  60. }
  61. var normalCompletion = true,
  62. didErr = false,
  63. err;
  64. return {
  65. s: function () {
  66. it = it.call(o);
  67. },
  68. n: function () {
  69. var step = it.next();
  70. normalCompletion = step.done;
  71. return step;
  72. },
  73. e: function (_e2) {
  74. didErr = true;
  75. err = _e2;
  76. },
  77. f: function () {
  78. try {
  79. if (!normalCompletion && it.return != null) it.return();
  80. } finally {
  81. if (didErr) throw err;
  82. }
  83. }
  84. };
  85. }
  86. function _unsupportedIterableToArray(o, minLen) {
  87. var _context6;
  88. if (!o) return;
  89. if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  90. var n = _sliceInstanceProperty(_context6 = Object.prototype.toString.call(o)).call(_context6, 8, -1);
  91. if (n === "Object" && o.constructor) n = o.constructor.name;
  92. if (n === "Map" || n === "Set") return _Array$from(o);
  93. if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  94. }
  95. function _arrayLikeToArray(arr, len) {
  96. if (len == null || len > arr.length) len = arr.length;
  97. for (var i = 0, arr2 = new Array(len); i < len; i++) {
  98. arr2[i] = arr[i];
  99. }
  100. return arr2;
  101. }
  102. function _createSuper(Derived) {
  103. var hasNativeReflectConstruct = _isNativeReflectConstruct();
  104. return function () {
  105. var Super = (0, _getPrototypeOf2.default)(Derived),
  106. result;
  107. if (hasNativeReflectConstruct) {
  108. var NewTarget = (0, _getPrototypeOf2.default)(this).constructor;
  109. result = _Reflect$construct(Super, arguments, NewTarget);
  110. } else {
  111. result = Super.apply(this, arguments);
  112. }
  113. return (0, _possibleConstructorReturn2.default)(this, result);
  114. };
  115. }
  116. function _isNativeReflectConstruct() {
  117. if (typeof Reflect === "undefined" || !_Reflect$construct) return false;
  118. if (_Reflect$construct.sham) return false;
  119. if (typeof Proxy === "function") return true;
  120. try {
  121. Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {}));
  122. return true;
  123. } catch (e) {
  124. return false;
  125. }
  126. } // The LiveQuery client inner state
  127. var CLIENT_STATE = {
  128. INITIALIZED: 'initialized',
  129. CONNECTING: 'connecting',
  130. CONNECTED: 'connected',
  131. CLOSED: 'closed',
  132. RECONNECTING: 'reconnecting',
  133. DISCONNECTED: 'disconnected'
  134. }; // The event type the LiveQuery client should sent to server
  135. var OP_TYPES = {
  136. CONNECT: 'connect',
  137. SUBSCRIBE: 'subscribe',
  138. UNSUBSCRIBE: 'unsubscribe',
  139. ERROR: 'error'
  140. }; // The event we get back from LiveQuery server
  141. var OP_EVENTS = {
  142. CONNECTED: 'connected',
  143. SUBSCRIBED: 'subscribed',
  144. UNSUBSCRIBED: 'unsubscribed',
  145. ERROR: 'error',
  146. CREATE: 'create',
  147. UPDATE: 'update',
  148. ENTER: 'enter',
  149. LEAVE: 'leave',
  150. DELETE: 'delete'
  151. }; // The event the LiveQuery client should emit
  152. var CLIENT_EMMITER_TYPES = {
  153. CLOSE: 'close',
  154. ERROR: 'error',
  155. OPEN: 'open'
  156. }; // The event the LiveQuery subscription should emit
  157. var SUBSCRIPTION_EMMITER_TYPES = {
  158. OPEN: 'open',
  159. CLOSE: 'close',
  160. ERROR: 'error',
  161. CREATE: 'create',
  162. UPDATE: 'update',
  163. ENTER: 'enter',
  164. LEAVE: 'leave',
  165. DELETE: 'delete'
  166. };
  167. var generateInterval = function (k) {
  168. return Math.random() * Math.min(30, Math.pow(2, k) - 1) * 1000;
  169. };
  170. /**
  171. * Creates a new LiveQueryClient.
  172. * Extends events.EventEmitter
  173. * <a href="https://nodejs.org/api/events.html#events_class_eventemitter">cloud functions</a>.
  174. *
  175. * A wrapper of a standard WebSocket client. We add several useful methods to
  176. * help you connect/disconnect to LiveQueryServer, subscribe/unsubscribe a ParseQuery easily.
  177. *
  178. * javascriptKey and masterKey are used for verifying the LiveQueryClient when it tries
  179. * to connect to the LiveQuery server
  180. *
  181. * We expose three events to help you monitor the status of the LiveQueryClient.
  182. *
  183. * <pre>
  184. * let Parse = require('parse/node');
  185. * let LiveQueryClient = Parse.LiveQueryClient;
  186. * let client = new LiveQueryClient({
  187. * applicationId: '',
  188. * serverURL: '',
  189. * javascriptKey: '',
  190. * masterKey: ''
  191. * });
  192. * </pre>
  193. *
  194. * Open - When we establish the WebSocket connection to the LiveQuery server, you'll get this event.
  195. * <pre>
  196. * client.on('open', () => {
  197. *
  198. * });</pre>
  199. *
  200. * Close - When we lose the WebSocket connection to the LiveQuery server, you'll get this event.
  201. * <pre>
  202. * client.on('close', () => {
  203. *
  204. * });</pre>
  205. *
  206. * Error - When some network error or LiveQuery server error happens, you'll get this event.
  207. * <pre>
  208. * client.on('error', (error) => {
  209. *
  210. * });</pre>
  211. *
  212. * @alias Parse.LiveQueryClient
  213. */
  214. var LiveQueryClient = /*#__PURE__*/function (_EventEmitter) {
  215. (0, _inherits2.default)(LiveQueryClient, _EventEmitter);
  216. var _super = _createSuper(LiveQueryClient);
  217. /**
  218. * @param {object} options
  219. * @param {string} options.applicationId - applicationId of your Parse app
  220. * @param {string} options.serverURL - <b>the URL of your LiveQuery server</b>
  221. * @param {string} options.javascriptKey (optional)
  222. * @param {string} options.masterKey (optional) Your Parse Master Key. (Node.js only!)
  223. * @param {string} options.sessionToken (optional)
  224. * @param {string} options.installationId (optional)
  225. */
  226. function LiveQueryClient(_ref) {
  227. var _this;
  228. var applicationId = _ref.applicationId,
  229. serverURL = _ref.serverURL,
  230. javascriptKey = _ref.javascriptKey,
  231. masterKey = _ref.masterKey,
  232. sessionToken = _ref.sessionToken,
  233. installationId = _ref.installationId;
  234. (0, _classCallCheck2.default)(this, LiveQueryClient);
  235. _this = _super.call(this);
  236. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "attempts", void 0);
  237. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "id", void 0);
  238. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "requestId", void 0);
  239. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "applicationId", void 0);
  240. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "serverURL", void 0);
  241. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "javascriptKey", void 0);
  242. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "masterKey", void 0);
  243. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "sessionToken", void 0);
  244. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "installationId", void 0);
  245. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "additionalProperties", void 0);
  246. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "connectPromise", void 0);
  247. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "subscriptions", void 0);
  248. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "socket", void 0);
  249. (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", void 0);
  250. if (!serverURL || (0, _indexOf.default)(serverURL).call(serverURL, 'ws') !== 0) {
  251. throw new Error('You need to set a proper Parse LiveQuery server url before using LiveQueryClient');
  252. }
  253. _this.reconnectHandle = null;
  254. _this.attempts = 1;
  255. _this.id = 0;
  256. _this.requestId = 1;
  257. _this.serverURL = serverURL;
  258. _this.applicationId = applicationId;
  259. _this.javascriptKey = javascriptKey || undefined;
  260. _this.masterKey = masterKey || undefined;
  261. _this.sessionToken = sessionToken || undefined;
  262. _this.installationId = installationId || undefined;
  263. _this.additionalProperties = true;
  264. _this.connectPromise = (0, _promiseUtils.resolvingPromise)();
  265. _this.subscriptions = new _map.default();
  266. _this.state = CLIENT_STATE.INITIALIZED; // adding listener so process does not crash
  267. // best practice is for developer to register their own listener
  268. _this.on('error', function () {});
  269. return _this;
  270. }
  271. (0, _createClass2.default)(LiveQueryClient, [{
  272. key: "shouldOpen",
  273. value: function ()
  274. /*: any*/
  275. {
  276. return this.state === CLIENT_STATE.INITIALIZED || this.state === CLIENT_STATE.DISCONNECTED;
  277. }
  278. /**
  279. * Subscribes to a ParseQuery
  280. *
  281. * If you provide the sessionToken, when the LiveQuery server gets ParseObject's
  282. * updates from parse server, it'll try to check whether the sessionToken fulfills
  283. * the ParseObject's ACL. The LiveQuery server will only send updates to clients whose
  284. * sessionToken is fit for the ParseObject's ACL. You can check the LiveQuery protocol
  285. * <a href="https://github.com/parse-community/parse-server/wiki/Parse-LiveQuery-Protocol-Specification">here</a> for more details. The subscription you get is the same subscription you get
  286. * from our Standard API.
  287. *
  288. * @param {object} query - the ParseQuery you want to subscribe to
  289. * @param {string} sessionToken (optional)
  290. * @returns {LiveQuerySubscription} subscription
  291. */
  292. }, {
  293. key: "subscribe",
  294. value: function (query
  295. /*: Object*/
  296. , sessionToken
  297. /*: ?string*/
  298. )
  299. /*: LiveQuerySubscription*/
  300. {
  301. var _this2 = this;
  302. if (!query) {
  303. return;
  304. }
  305. var className = query.className;
  306. var queryJSON = query.toJSON();
  307. var where = queryJSON.where;
  308. var fields = (0, _keys.default)(queryJSON) ? (0, _keys.default)(queryJSON).split(',') : undefined;
  309. var subscribeRequest = {
  310. op: OP_TYPES.SUBSCRIBE,
  311. requestId: this.requestId,
  312. query: {
  313. className: className,
  314. where: where,
  315. fields: fields
  316. }
  317. };
  318. if (sessionToken) {
  319. subscribeRequest.sessionToken = sessionToken;
  320. }
  321. var subscription = new _LiveQuerySubscription.default(this.requestId, query, sessionToken);
  322. this.subscriptions.set(this.requestId, subscription);
  323. this.requestId += 1;
  324. this.connectPromise.then(function () {
  325. _this2.socket.send((0, _stringify.default)(subscribeRequest));
  326. });
  327. return subscription;
  328. }
  329. /**
  330. * After calling unsubscribe you'll stop receiving events from the subscription object.
  331. *
  332. * @param {object} subscription - subscription you would like to unsubscribe from.
  333. */
  334. }, {
  335. key: "unsubscribe",
  336. value: function (subscription
  337. /*: Object*/
  338. ) {
  339. var _this3 = this;
  340. if (!subscription) {
  341. return;
  342. }
  343. this.subscriptions.delete(subscription.id);
  344. var unsubscribeRequest = {
  345. op: OP_TYPES.UNSUBSCRIBE,
  346. requestId: subscription.id
  347. };
  348. this.connectPromise.then(function () {
  349. _this3.socket.send((0, _stringify.default)(unsubscribeRequest));
  350. });
  351. }
  352. /**
  353. * After open is called, the LiveQueryClient will try to send a connect request
  354. * to the LiveQuery server.
  355. *
  356. */
  357. }, {
  358. key: "open",
  359. value: function () {
  360. var _this4 = this;
  361. var WebSocketImplementation = _CoreManager.default.getWebSocketController();
  362. if (!WebSocketImplementation) {
  363. this.emit(CLIENT_EMMITER_TYPES.ERROR, 'Can not find WebSocket implementation');
  364. return;
  365. }
  366. if (this.state !== CLIENT_STATE.RECONNECTING) {
  367. this.state = CLIENT_STATE.CONNECTING;
  368. }
  369. this.socket = new WebSocketImplementation(this.serverURL); // Bind WebSocket callbacks
  370. this.socket.onopen = function () {
  371. _this4._handleWebSocketOpen();
  372. };
  373. this.socket.onmessage = function (event) {
  374. _this4._handleWebSocketMessage(event);
  375. };
  376. this.socket.onclose = function () {
  377. _this4._handleWebSocketClose();
  378. };
  379. this.socket.onerror = function (error) {
  380. _this4._handleWebSocketError(error);
  381. };
  382. }
  383. }, {
  384. key: "resubscribe",
  385. value: function () {
  386. var _context,
  387. _this5 = this;
  388. (0, _forEach.default)(_context = this.subscriptions).call(_context, function (subscription, requestId) {
  389. var query = subscription.query;
  390. var queryJSON = query.toJSON();
  391. var where = queryJSON.where;
  392. var fields = (0, _keys.default)(queryJSON) ? (0, _keys.default)(queryJSON).split(',') : undefined;
  393. var className = query.className;
  394. var sessionToken = subscription.sessionToken;
  395. var subscribeRequest = {
  396. op: OP_TYPES.SUBSCRIBE,
  397. requestId: requestId,
  398. query: {
  399. className: className,
  400. where: where,
  401. fields: fields
  402. }
  403. };
  404. if (sessionToken) {
  405. subscribeRequest.sessionToken = sessionToken;
  406. }
  407. _this5.connectPromise.then(function () {
  408. _this5.socket.send((0, _stringify.default)(subscribeRequest));
  409. });
  410. });
  411. }
  412. /**
  413. * This method will close the WebSocket connection to this LiveQueryClient,
  414. * cancel the auto reconnect and unsubscribe all subscriptions based on it.
  415. *
  416. */
  417. }, {
  418. key: "close",
  419. value: function () {
  420. var _context2;
  421. if (this.state === CLIENT_STATE.INITIALIZED || this.state === CLIENT_STATE.DISCONNECTED) {
  422. return;
  423. }
  424. this.state = CLIENT_STATE.DISCONNECTED;
  425. this.socket.close(); // Notify each subscription about the close
  426. var _iterator = _createForOfIteratorHelper((0, _values.default)(_context2 = this.subscriptions).call(_context2)),
  427. _step;
  428. try {
  429. for (_iterator.s(); !(_step = _iterator.n()).done;) {
  430. var subscription = _step.value;
  431. subscription.subscribed = false;
  432. subscription.emit(SUBSCRIPTION_EMMITER_TYPES.CLOSE);
  433. }
  434. } catch (err) {
  435. _iterator.e(err);
  436. } finally {
  437. _iterator.f();
  438. }
  439. this._handleReset();
  440. this.emit(CLIENT_EMMITER_TYPES.CLOSE);
  441. } // ensure we start with valid state if connect is called again after close
  442. }, {
  443. key: "_handleReset",
  444. value: function () {
  445. this.attempts = 1;
  446. this.id = 0;
  447. this.requestId = 1;
  448. this.connectPromise = (0, _promiseUtils.resolvingPromise)();
  449. this.subscriptions = new _map.default();
  450. }
  451. }, {
  452. key: "_handleWebSocketOpen",
  453. value: function () {
  454. this.attempts = 1;
  455. var connectRequest = {
  456. op: OP_TYPES.CONNECT,
  457. applicationId: this.applicationId,
  458. javascriptKey: this.javascriptKey,
  459. masterKey: this.masterKey,
  460. sessionToken: this.sessionToken
  461. };
  462. if (this.additionalProperties) {
  463. connectRequest.installationId = this.installationId;
  464. }
  465. this.socket.send((0, _stringify.default)(connectRequest));
  466. }
  467. }, {
  468. key: "_handleWebSocketMessage",
  469. value: function (event
  470. /*: any*/
  471. ) {
  472. var data = event.data;
  473. if (typeof data === 'string') {
  474. data = JSON.parse(data);
  475. }
  476. var subscription = null;
  477. if (data.requestId) {
  478. subscription = this.subscriptions.get(data.requestId);
  479. }
  480. var response = {
  481. clientId: data.clientId,
  482. installationId: data.installationId
  483. };
  484. switch (data.op) {
  485. case OP_EVENTS.CONNECTED:
  486. if (this.state === CLIENT_STATE.RECONNECTING) {
  487. this.resubscribe();
  488. }
  489. this.emit(CLIENT_EMMITER_TYPES.OPEN);
  490. this.id = data.clientId;
  491. this.connectPromise.resolve();
  492. this.state = CLIENT_STATE.CONNECTED;
  493. break;
  494. case OP_EVENTS.SUBSCRIBED:
  495. if (subscription) {
  496. subscription.subscribed = true;
  497. subscription.subscribePromise.resolve();
  498. (0, _setTimeout2.default)(function () {
  499. return subscription.emit(SUBSCRIPTION_EMMITER_TYPES.OPEN, response);
  500. }, 200);
  501. }
  502. break;
  503. case OP_EVENTS.ERROR:
  504. if (data.requestId) {
  505. if (subscription) {
  506. subscription.subscribePromise.resolve();
  507. (0, _setTimeout2.default)(function () {
  508. return subscription.emit(SUBSCRIPTION_EMMITER_TYPES.ERROR, data.error);
  509. }, 200);
  510. }
  511. } else {
  512. this.emit(CLIENT_EMMITER_TYPES.ERROR, data.error);
  513. }
  514. if (data.error === 'Additional properties not allowed') {
  515. this.additionalProperties = false;
  516. }
  517. if (data.reconnect) {
  518. this._handleReconnect();
  519. }
  520. break;
  521. case OP_EVENTS.UNSUBSCRIBED:
  522. // We have already deleted subscription in unsubscribe(), do nothing here
  523. break;
  524. default:
  525. {
  526. // create, update, enter, leave, delete cases
  527. if (!subscription) {
  528. break;
  529. }
  530. var override = false;
  531. if (data.original) {
  532. override = true;
  533. delete data.original.__type; // Check for removed fields
  534. for (var field in data.original) {
  535. if (!(field in data.object)) {
  536. data.object[field] = undefined;
  537. }
  538. }
  539. data.original = _ParseObject.default.fromJSON(data.original, false);
  540. }
  541. delete data.object.__type;
  542. var parseObject = _ParseObject.default.fromJSON(data.object, override);
  543. if (data.original) {
  544. subscription.emit(data.op, parseObject, data.original, response);
  545. } else {
  546. subscription.emit(data.op, parseObject, response);
  547. }
  548. var localDatastore = _CoreManager.default.getLocalDatastore();
  549. if (override && localDatastore.isEnabled) {
  550. localDatastore._updateObjectIfPinned(parseObject).then(function () {});
  551. }
  552. }
  553. }
  554. }
  555. }, {
  556. key: "_handleWebSocketClose",
  557. value: function () {
  558. var _context3;
  559. if (this.state === CLIENT_STATE.DISCONNECTED) {
  560. return;
  561. }
  562. this.state = CLIENT_STATE.CLOSED;
  563. this.emit(CLIENT_EMMITER_TYPES.CLOSE); // Notify each subscription about the close
  564. var _iterator2 = _createForOfIteratorHelper((0, _values.default)(_context3 = this.subscriptions).call(_context3)),
  565. _step2;
  566. try {
  567. for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
  568. var subscription = _step2.value;
  569. subscription.emit(SUBSCRIPTION_EMMITER_TYPES.CLOSE);
  570. }
  571. } catch (err) {
  572. _iterator2.e(err);
  573. } finally {
  574. _iterator2.f();
  575. }
  576. this._handleReconnect();
  577. }
  578. }, {
  579. key: "_handleWebSocketError",
  580. value: function (error
  581. /*: any*/
  582. ) {
  583. var _context4;
  584. this.emit(CLIENT_EMMITER_TYPES.ERROR, error);
  585. var _iterator3 = _createForOfIteratorHelper((0, _values.default)(_context4 = this.subscriptions).call(_context4)),
  586. _step3;
  587. try {
  588. for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
  589. var subscription = _step3.value;
  590. subscription.emit(SUBSCRIPTION_EMMITER_TYPES.ERROR, error);
  591. }
  592. } catch (err) {
  593. _iterator3.e(err);
  594. } finally {
  595. _iterator3.f();
  596. }
  597. this._handleReconnect();
  598. }
  599. }, {
  600. key: "_handleReconnect",
  601. value: function () {
  602. var _context5,
  603. _this6 = this; // if closed or currently reconnecting we stop attempting to reconnect
  604. if (this.state === CLIENT_STATE.DISCONNECTED) {
  605. return;
  606. }
  607. this.state = CLIENT_STATE.RECONNECTING;
  608. var time = generateInterval(this.attempts); // handle case when both close/error occur at frequent rates we ensure we do not reconnect unnecessarily.
  609. // we're unable to distinguish different between close/error when we're unable to reconnect therefore
  610. // we try to reconnect in both cases
  611. // server side ws and browser WebSocket behave differently in when close/error get triggered
  612. if (this.reconnectHandle) {
  613. clearTimeout(this.reconnectHandle);
  614. }
  615. this.reconnectHandle = (0, _setTimeout2.default)((0, _bind.default)(_context5 = function () {
  616. _this6.attempts++;
  617. _this6.connectPromise = (0, _promiseUtils.resolvingPromise)();
  618. _this6.open();
  619. }).call(_context5, this), time);
  620. }
  621. }]);
  622. return LiveQueryClient;
  623. }(_EventEmitter2.default);
  624. _CoreManager.default.setWebSocketController(typeof WebSocket === 'function' || (typeof WebSocket === "undefined" ? "undefined" : (0, _typeof2.default)(WebSocket)) === 'object' ? WebSocket : null);
  625. var _default = LiveQueryClient;
  626. exports.default = _default;