polfan-server-js-client 0.2.105 → 0.2.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -547,6 +547,53 @@ var ObservableIndexedObjectCollection = /*#__PURE__*/function (_IndexedObjectCol
547
547
  });
548
548
  }
549
549
  }
550
+
551
+ /**
552
+ * Bring the collection to exactly match the provided items: upsert every
553
+ * provided item and remove any existing item whose id is not present in the
554
+ * provided set. Emits at most a single `change` event describing both the
555
+ * set and the deleted ids, so bound consumers can update in place without
556
+ * ever observing an intermediate empty state (unlike deleteAll + set).
557
+ */
558
+ }, {
559
+ key: "reconcile",
560
+ value: function reconcile() {
561
+ var _this8 = this,
562
+ _this$_items3;
563
+ for (var _len8 = arguments.length, items = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
564
+ items[_key8] = arguments[_key8];
565
+ }
566
+ var incomingIds = new Set(items.map(function (item) {
567
+ return _this8.getId(item);
568
+ }));
569
+ var deletedItems = [];
570
+ var _iterator3 = _createForOfIteratorHelper(this.items),
571
+ _step3;
572
+ try {
573
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
574
+ var existing = _step3.value;
575
+ var _id2 = this.getId(existing);
576
+ if (!incomingIds.has(_id2)) {
577
+ deletedItems.push(_id2);
578
+ }
579
+ }
580
+ } catch (err) {
581
+ _iterator3.e(err);
582
+ } finally {
583
+ _iterator3.f();
584
+ }
585
+ if (!items.length && !deletedItems.length) {
586
+ return;
587
+ }
588
+ (_this$_items3 = this._items)["delete"].apply(_this$_items3, deletedItems);
589
+ _superPropGet(ObservableIndexedObjectCollection, "set", this, 3)(items);
590
+ this.eventTarget.emit('change', {
591
+ setItems: items.map(function (item) {
592
+ return _this8.getId(item);
593
+ }),
594
+ deletedItems: deletedItems
595
+ });
596
+ }
550
597
  }, {
551
598
  key: "createMirror",
552
599
  value: function createMirror() {
@@ -781,11 +828,15 @@ var TraversableRemoteCollection = /*#__PURE__*/function (_ObservableIndexedObj)
781
828
  key: "resetToLatest",
782
829
  value: function () {
783
830
  var _resetToLatest = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
784
- var result, originalState;
831
+ var force,
832
+ result,
833
+ originalState,
834
+ _args = arguments;
785
835
  return _regenerator().w(function (_context) {
786
836
  while (1) switch (_context.p = _context.n) {
787
837
  case 0:
788
- if (!(this.internalState.ongoing || this.internalState.current === WindowState.LATEST)) {
838
+ force = _args.length > 0 && _args[0] !== undefined ? _args[0] : false;
839
+ if (!(this.internalState.ongoing || !force && this.internalState.current === WindowState.LATEST)) {
789
840
  _context.n = 1;
790
841
  break;
791
842
  }
@@ -1133,16 +1184,19 @@ var TopicHistoryWindow = /*#__PURE__*/function (_TraversableRemoteCol) {
1133
1184
  key: "resetToLatest",
1134
1185
  value: function () {
1135
1186
  var _resetToLatest2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
1187
+ var force,
1188
+ _args7 = arguments;
1136
1189
  return _regenerator().w(function (_context7) {
1137
1190
  while (1) switch (_context7.n) {
1138
1191
  case 0:
1192
+ force = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : false;
1139
1193
  if (!this.internalState.traverseLock) {
1140
1194
  _context7.n = 1;
1141
1195
  break;
1142
1196
  }
1143
1197
  return _context7.a(2);
1144
1198
  case 1:
1145
- return _context7.a(2, TopicHistoryWindow_superPropGet(TopicHistoryWindow, "resetToLatest", this, 3)([]));
1199
+ return _context7.a(2, TopicHistoryWindow_superPropGet(TopicHistoryWindow, "resetToLatest", this, 3)([force]));
1146
1200
  }
1147
1201
  }, _callee7, this);
1148
1202
  }));
@@ -1618,43 +1672,104 @@ var RoomMessagesHistory = /*#__PURE__*/function () {
1618
1672
  return _getMessagesWindow.apply(this, arguments);
1619
1673
  }
1620
1674
  return getMessagesWindow;
1621
- }())
1675
+ }()
1676
+ /**
1677
+ * Re-synchronise this room's history after a reconnect without discarding
1678
+ * the existing window objects (which would blank the UI and, for ephemeral
1679
+ * rooms, permanently drop live-only history).
1680
+ *
1681
+ * The window bindings are preserved; only windows that the application had
1682
+ * actually pulled to the latest page (state === LATEST) are refreshed, with
1683
+ * a single resetToLatest instead of a chain of catch-up requests. Windows
1684
+ * that were never pulled (LIVE) or belong to an ephemeral room are left
1685
+ * untouched so their in-memory context survives the reconnect.
1686
+ */
1687
+ )
1622
1688
  }, {
1623
- key: "handleRoomUpdated",
1624
- value: function () {
1625
- var _handleRoomUpdated = RoomMessagesHistory_asyncToGenerator(/*#__PURE__*/RoomMessagesHistory_regenerator().m(function _callee2(ev) {
1689
+ key: "resync",
1690
+ value: (function () {
1691
+ var _resync = RoomMessagesHistory_asyncToGenerator(/*#__PURE__*/RoomMessagesHistory_regenerator().m(function _callee2(room) {
1626
1692
  var _i, _Array$from, _Array$from$_i, window;
1627
1693
  return RoomMessagesHistory_regenerator().w(function (_context2) {
1628
1694
  while (1) switch (_context2.n) {
1629
1695
  case 0:
1630
- if (!(this.room.id === ev.room.id)) {
1631
- _context2.n = 3;
1632
- break;
1633
- }
1634
- this.room = ev.room;
1635
- this.updateTraverseLock(ev.room);
1636
- if (ev.room.defaultTopic) {
1637
- this.createHistoryWindowForTopic(ev.room.defaultTopic);
1696
+ this.room = room;
1697
+ this.updateTraverseLock(room);
1698
+ if (this.room.defaultTopic) {
1699
+ this.createHistoryWindowForTopic(this.room.defaultTopic);
1638
1700
  }
1639
1701
  _i = 0, _Array$from = Array.from(this.historyWindows.items);
1640
1702
  case 1:
1641
1703
  if (!(_i < _Array$from.length)) {
1642
- _context2.n = 3;
1704
+ _context2.n = 5;
1643
1705
  break;
1644
1706
  }
1645
1707
  _Array$from$_i = RoomMessagesHistory_slicedToArray(_Array$from[_i], 2), window = _Array$from$_i[1];
1646
1708
  _context2.n = 2;
1647
1709
  return window.setTraverseLock(this.traverseLock);
1648
1710
  case 2:
1711
+ if (!this.traverseLock) {
1712
+ _context2.n = 3;
1713
+ break;
1714
+ }
1715
+ return _context2.a(3, 4);
1716
+ case 3:
1717
+ if (!(window.state === WindowState.LATEST)) {
1718
+ _context2.n = 4;
1719
+ break;
1720
+ }
1721
+ _context2.n = 4;
1722
+ return window.resetToLatest(true);
1723
+ case 4:
1649
1724
  _i++;
1650
1725
  _context2.n = 1;
1651
1726
  break;
1652
- case 3:
1727
+ case 5:
1653
1728
  return _context2.a(2);
1654
1729
  }
1655
1730
  }, _callee2, this);
1656
1731
  }));
1657
- function handleRoomUpdated(_x2) {
1732
+ function resync(_x2) {
1733
+ return _resync.apply(this, arguments);
1734
+ }
1735
+ return resync;
1736
+ }())
1737
+ }, {
1738
+ key: "handleRoomUpdated",
1739
+ value: function () {
1740
+ var _handleRoomUpdated = RoomMessagesHistory_asyncToGenerator(/*#__PURE__*/RoomMessagesHistory_regenerator().m(function _callee3(ev) {
1741
+ var _i2, _Array$from2, _Array$from2$_i, window;
1742
+ return RoomMessagesHistory_regenerator().w(function (_context3) {
1743
+ while (1) switch (_context3.n) {
1744
+ case 0:
1745
+ if (!(this.room.id === ev.room.id)) {
1746
+ _context3.n = 3;
1747
+ break;
1748
+ }
1749
+ this.room = ev.room;
1750
+ this.updateTraverseLock(ev.room);
1751
+ if (ev.room.defaultTopic) {
1752
+ this.createHistoryWindowForTopic(ev.room.defaultTopic);
1753
+ }
1754
+ _i2 = 0, _Array$from2 = Array.from(this.historyWindows.items);
1755
+ case 1:
1756
+ if (!(_i2 < _Array$from2.length)) {
1757
+ _context3.n = 3;
1758
+ break;
1759
+ }
1760
+ _Array$from2$_i = RoomMessagesHistory_slicedToArray(_Array$from2[_i2], 2), window = _Array$from2$_i[1];
1761
+ _context3.n = 2;
1762
+ return window.setTraverseLock(this.traverseLock);
1763
+ case 2:
1764
+ _i2++;
1765
+ _context3.n = 1;
1766
+ break;
1767
+ case 3:
1768
+ return _context3.a(2);
1769
+ }
1770
+ }, _callee3, this);
1771
+ }));
1772
+ function handleRoomUpdated(_x3) {
1658
1773
  return _handleRoomUpdated.apply(this, arguments);
1659
1774
  }
1660
1775
  return handleRoomUpdated;
@@ -1718,6 +1833,9 @@ var RoomMessagesHistory = /*#__PURE__*/function () {
1718
1833
  }();
1719
1834
  ;// ./src/state-tracker/MessagesManager.ts
1720
1835
  function MessagesManager_typeof(o) { "@babel/helpers - typeof"; return MessagesManager_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, MessagesManager_typeof(o); }
1836
+ function MessagesManager_createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = MessagesManager_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
1837
+ function MessagesManager_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return MessagesManager_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? MessagesManager_arrayLikeToArray(r, a) : void 0; } }
1838
+ function MessagesManager_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
1721
1839
  function MessagesManager_regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return MessagesManager_regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (MessagesManager_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, MessagesManager_regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, MessagesManager_regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), MessagesManager_regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", MessagesManager_regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), MessagesManager_regeneratorDefine2(u), MessagesManager_regeneratorDefine2(u, o, "Generator"), MessagesManager_regeneratorDefine2(u, n, function () { return this; }), MessagesManager_regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (MessagesManager_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
1722
1840
  function MessagesManager_regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } MessagesManager_regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { MessagesManager_regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, MessagesManager_regeneratorDefine2(e, r, n, t); }
1723
1841
  function MessagesManager_asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
@@ -1840,11 +1958,38 @@ var MessagesManager = /*#__PURE__*/function () {
1840
1958
  }, {
1841
1959
  key: "handleSession",
1842
1960
  value: function handleSession(ev) {
1843
- var _this2 = this;
1844
- this.roomHistories.deleteAll();
1845
- ev.state.rooms.forEach(function (room) {
1846
- return _this2.createHistoryForNewRoom(room);
1847
- });
1961
+ var stateRoomIds = new Set(ev.state.rooms.map(function (room) {
1962
+ return room.id;
1963
+ }));
1964
+
1965
+ // Drop histories only for rooms that no longer exist server-side.
1966
+ for (var _i = 0, _Array$from = Array.from(this.roomHistories.items.keys()); _i < _Array$from.length; _i++) {
1967
+ var roomId = _Array$from[_i];
1968
+ if (!stateRoomIds.has(roomId)) {
1969
+ this.roomHistories["delete"](roomId);
1970
+ }
1971
+ }
1972
+
1973
+ // Keep existing histories (preserving loaded messages and, crucially,
1974
+ // live-only ephemeral history), create histories for newly joined
1975
+ // rooms, and resync survivors against the fresh room snapshot.
1976
+ var _iterator = MessagesManager_createForOfIteratorHelper(ev.state.rooms),
1977
+ _step;
1978
+ try {
1979
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1980
+ var room = _step.value;
1981
+ var history = this.roomHistories.get(room.id);
1982
+ if (history) {
1983
+ void history.resync(room);
1984
+ } else {
1985
+ this.createHistoryForNewRoom(room);
1986
+ }
1987
+ }
1988
+ } catch (err) {
1989
+ _iterator.e(err);
1990
+ } finally {
1991
+ _iterator.f();
1992
+ }
1848
1993
  this.deferredSession.resolve();
1849
1994
  }
1850
1995
  }]);
@@ -1889,6 +2034,11 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
1889
2034
  FollowedTopicsManager_defineProperty(_this, "followedTopicsPromises", new PromiseRegistry());
1890
2035
  FollowedTopicsManager_defineProperty(_this, "deferredSession", new DeferredTask());
1891
2036
  FollowedTopicsManager_defineProperty(_this, "summariesCache", new Map());
2037
+ /**
2038
+ * Rooms whose cached followed-topics are stale after a reconnect and must
2039
+ * be refetched (and reconciled in place) the next time they are accessed.
2040
+ */
2041
+ FollowedTopicsManager_defineProperty(_this, "staleRooms", new Set());
1892
2042
  _this.tracker = tracker;
1893
2043
  _this.tracker.client.on('Session', function (ev) {
1894
2044
  return _this.handleSession(ev);
@@ -1934,7 +2084,7 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
1934
2084
  value: (function () {
1935
2085
  var _cacheForSpace = FollowedTopicsManager_asyncToGenerator(/*#__PURE__*/FollowedTopicsManager_regenerator().m(function _callee2(spaceId) {
1936
2086
  var _this2 = this;
1937
- var rooms, roomIds, isAlreadyCached, spaceRegistryKey, _t;
2087
+ var rooms, roomIds, needsFetch, spaceRegistryKey, _t;
1938
2088
  return FollowedTopicsManager_regenerator().w(function (_context2) {
1939
2089
  while (1) switch (_context2.n) {
1940
2090
  case 0:
@@ -1971,10 +2121,10 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
1971
2121
  }
1972
2122
  return _context2.a(2);
1973
2123
  case 5:
1974
- isAlreadyCached = roomIds.every(function (roomId) {
1975
- return _this2.followedTopics.has(roomId);
2124
+ needsFetch = roomIds.some(function (roomId) {
2125
+ return !_this2.followedTopics.has(roomId) || _this2.staleRooms.has(roomId);
1976
2126
  });
1977
- if (!isAlreadyCached) {
2127
+ if (needsFetch) {
1978
2128
  _context2.n = 6;
1979
2129
  break;
1980
2130
  }
@@ -2001,7 +2151,7 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2001
2151
  }
2002
2152
  throw result.error;
2003
2153
  case 2:
2004
- _this2.setFollowedTopicsArray(roomIds, result.data.followedTopics);
2154
+ _this2.reconcileRoomsFollowedTopics(roomIds, result.data.followedTopics);
2005
2155
  case 3:
2006
2156
  return _context.a(2);
2007
2157
  }
@@ -2042,7 +2192,7 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2042
2192
  }
2043
2193
  return _context4.a(2, undefined);
2044
2194
  case 2:
2045
- if (this.followedTopics.has(roomId)) {
2195
+ if (!(!this.followedTopics.has(roomId) || this.staleRooms.has(roomId))) {
2046
2196
  _context4.n = 3;
2047
2197
  break;
2048
2198
  }
@@ -2066,7 +2216,8 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2066
2216
  }
2067
2217
  throw result.error;
2068
2218
  case 2:
2069
- _this3.setFollowedTopicsArray([roomId], result.data.followedTopics);
2219
+ _this3.applyRoomFollowedTopics(roomId, result.data.followedTopics);
2220
+ _this3.invalidateUnreadSummaries(roomId);
2070
2221
  case 3:
2071
2222
  return _context3.a(2);
2072
2223
  }
@@ -2324,7 +2475,22 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2324
2475
  }, {
2325
2476
  key: "handleSession",
2326
2477
  value: function handleSession(ev) {
2327
- this.followedTopics.deleteAll();
2478
+ // Keep cached followed-topic collections (they drive unread indicators
2479
+ // that would otherwise blank on reconnect), but mark them stale and drop
2480
+ // the fetch guards so the next access/caching refetches and reconciles
2481
+ // them in place.
2482
+ var _iterator4 = FollowedTopicsManager_createForOfIteratorHelper(this.followedTopics.items.keys()),
2483
+ _step4;
2484
+ try {
2485
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
2486
+ var roomId = _step4.value;
2487
+ this.staleRooms.add(roomId);
2488
+ }
2489
+ } catch (err) {
2490
+ _iterator4.e(err);
2491
+ } finally {
2492
+ _iterator4.f();
2493
+ }
2328
2494
  this.followedTopicsPromises.forgetAll();
2329
2495
  this.invalidateUnreadSummaries();
2330
2496
  this.deferredSession.resolve();
@@ -2424,34 +2590,34 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2424
2590
  if (topicId) {
2425
2591
  this.summariesCache["delete"]("topic:".concat(roomId, ":").concat(topicId));
2426
2592
  } else {
2427
- var _iterator4 = FollowedTopicsManager_createForOfIteratorHelper(this.summariesCache.keys()),
2428
- _step4;
2593
+ var _iterator5 = FollowedTopicsManager_createForOfIteratorHelper(this.summariesCache.keys()),
2594
+ _step5;
2429
2595
  try {
2430
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
2431
- var key = _step4.value;
2596
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
2597
+ var key = _step5.value;
2432
2598
  if (key.startsWith("topic:".concat(roomId, ":"))) {
2433
2599
  this.summariesCache["delete"](key);
2434
2600
  }
2435
2601
  }
2436
2602
  } catch (err) {
2437
- _iterator4.e(err);
2603
+ _iterator5.e(err);
2438
2604
  } finally {
2439
- _iterator4.f();
2605
+ _iterator5.f();
2440
2606
  }
2441
2607
  }
2442
- var _iterator5 = FollowedTopicsManager_createForOfIteratorHelper(this.summariesCache.keys()),
2443
- _step5;
2608
+ var _iterator6 = FollowedTopicsManager_createForOfIteratorHelper(this.summariesCache.keys()),
2609
+ _step6;
2444
2610
  try {
2445
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
2446
- var _key2 = _step5.value;
2611
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
2612
+ var _key2 = _step6.value;
2447
2613
  if (_key2.startsWith('space:') || _key2 === 'spaceless') {
2448
2614
  this.summariesCache["delete"](_key2);
2449
2615
  }
2450
2616
  }
2451
2617
  } catch (err) {
2452
- _iterator5.e(err);
2618
+ _iterator6.e(err);
2453
2619
  } finally {
2454
- _iterator5.f();
2620
+ _iterator6.f();
2455
2621
  }
2456
2622
  } else {
2457
2623
  this.summariesCache.clear();
@@ -2466,11 +2632,11 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2466
2632
  roomIds.forEach(function (roomId) {
2467
2633
  _this5.summariesCache["delete"]("room:".concat(roomId));
2468
2634
  });
2469
- var _iterator6 = FollowedTopicsManager_createForOfIteratorHelper(this.summariesCache.keys()),
2470
- _step6;
2635
+ var _iterator7 = FollowedTopicsManager_createForOfIteratorHelper(this.summariesCache.keys()),
2636
+ _step7;
2471
2637
  try {
2472
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
2473
- var key = _step6.value;
2638
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
2639
+ var key = _step7.value;
2474
2640
  if (key.startsWith('space:') || key === 'spaceless') {
2475
2641
  this.summariesCache["delete"](key);
2476
2642
  continue;
@@ -2483,9 +2649,9 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2483
2649
  }
2484
2650
  }
2485
2651
  } catch (err) {
2486
- _iterator6.e(err);
2652
+ _iterator7.e(err);
2487
2653
  } finally {
2488
- _iterator6.f();
2654
+ _iterator7.f();
2489
2655
  }
2490
2656
  this.emit('change');
2491
2657
  }
@@ -2563,27 +2729,66 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2563
2729
  }
2564
2730
  return updateLocallyFollowedTopicOnNewMessage;
2565
2731
  }()
2732
+ /**
2733
+ * Reconcile the followed-topics collection for a single room to exactly
2734
+ * match the provided list (upsert present, drop absent) without emitting an
2735
+ * intermediate empty state, and clear its stale marker. Does not touch the
2736
+ * unread summaries cache - callers decide how to invalidate it.
2737
+ */
2738
+ }, {
2739
+ key: "applyRoomFollowedTopics",
2740
+ value: function applyRoomFollowedTopics(roomId, followedTopics) {
2741
+ var _this$followedTopics$5;
2742
+ if (!this.followedTopics.has(roomId)) {
2743
+ this.followedTopics.set([roomId, new ObservableIndexedObjectCollection(function (followedTopic) {
2744
+ return followedTopic.location.topicId;
2745
+ })]);
2746
+ }
2747
+ (_this$followedTopics$5 = this.followedTopics.get(roomId)).reconcile.apply(_this$followedTopics$5, FollowedTopicsManager_toConsumableArray(followedTopics));
2748
+ this.staleRooms["delete"](roomId);
2749
+ }
2750
+
2751
+ /**
2752
+ * Reconcile a batch of rooms from a single bulk GetFollowedTopics response.
2753
+ * Rooms with no followed topics in the response are reconciled to empty, so
2754
+ * topics unfollowed/removed during the downtime are correctly dropped.
2755
+ */
2756
+ }, {
2757
+ key: "reconcileRoomsFollowedTopics",
2758
+ value: function reconcileRoomsFollowedTopics(roomIds, followedTopics) {
2759
+ var _this6 = this;
2760
+ var roomToTopics = {};
2761
+ followedTopics.forEach(function (followedTopic) {
2762
+ var _followedTopic$locati, _roomToTopics$_follow;
2763
+ ((_roomToTopics$_follow = roomToTopics[_followedTopic$locati = followedTopic.location.roomId]) !== null && _roomToTopics$_follow !== void 0 ? _roomToTopics$_follow : roomToTopics[_followedTopic$locati] = []).push(followedTopic);
2764
+ });
2765
+ roomIds.forEach(function (roomId) {
2766
+ var _roomToTopics$roomId;
2767
+ return _this6.applyRoomFollowedTopics(roomId, (_roomToTopics$roomId = roomToTopics[roomId]) !== null && _roomToTopics$roomId !== void 0 ? _roomToTopics$roomId : []);
2768
+ });
2769
+ this.invalidateUnreadSummariesForRooms(roomIds);
2770
+ }
2566
2771
  }, {
2567
2772
  key: "setFollowedTopicsArray",
2568
2773
  value: function setFollowedTopicsArray(roomIds, followedTopics) {
2569
- var _this6 = this;
2774
+ var _this7 = this;
2570
2775
  var roomToTopics = {};
2571
2776
 
2572
2777
  // Reassign followed topics to limit collection change event emit
2573
2778
  followedTopics.forEach(function (followedTopic) {
2574
- var _followedTopic$locati, _roomToTopics$_follow;
2575
- (_roomToTopics$_follow = roomToTopics[_followedTopic$locati = followedTopic.location.roomId]) !== null && _roomToTopics$_follow !== void 0 ? _roomToTopics$_follow : roomToTopics[_followedTopic$locati] = [];
2779
+ var _followedTopic$locati2, _roomToTopics$_follow2;
2780
+ (_roomToTopics$_follow2 = roomToTopics[_followedTopic$locati2 = followedTopic.location.roomId]) !== null && _roomToTopics$_follow2 !== void 0 ? _roomToTopics$_follow2 : roomToTopics[_followedTopic$locati2] = [];
2576
2781
  roomToTopics[followedTopic.location.roomId].push(followedTopic);
2577
2782
  });
2578
2783
  roomIds.forEach(function (roomId) {
2579
- if (!_this6.followedTopics.has(roomId)) {
2580
- _this6.followedTopics.set([roomId, new ObservableIndexedObjectCollection(function (followedTopic) {
2784
+ if (!_this7.followedTopics.has(roomId)) {
2785
+ _this7.followedTopics.set([roomId, new ObservableIndexedObjectCollection(function (followedTopic) {
2581
2786
  return followedTopic.location.topicId;
2582
2787
  })]);
2583
2788
  }
2584
2789
  if (roomToTopics[roomId]) {
2585
- var _this6$followedTopics;
2586
- (_this6$followedTopics = _this6.followedTopics.get(roomId)).set.apply(_this6$followedTopics, FollowedTopicsManager_toConsumableArray(roomToTopics[roomId]));
2790
+ var _this7$followedTopics;
2791
+ (_this7$followedTopics = _this7.followedTopics.get(roomId)).set.apply(_this7$followedTopics, FollowedTopicsManager_toConsumableArray(roomToTopics[roomId]));
2587
2792
  }
2588
2793
  });
2589
2794
  this.invalidateUnreadSummariesForRooms(roomIds);
@@ -2593,6 +2798,7 @@ var FollowedTopicsManager = /*#__PURE__*/function (_EventTarget) {
2593
2798
  value: function clearRoomFollowedTopicsStructures(roomId) {
2594
2799
  this.followedTopics["delete"](roomId);
2595
2800
  this.followedTopicsPromises.forget(roomId);
2801
+ this.staleRooms["delete"](roomId);
2596
2802
  this.invalidateUnreadSummaries(roomId);
2597
2803
  }
2598
2804
  }]);
@@ -3108,16 +3314,39 @@ var RoomsManager = /*#__PURE__*/function () {
3108
3314
  var _member$user$id2, _member$user2;
3109
3315
  return (_member$user$id2 = (_member$user2 = member.user) === null || _member$user2 === void 0 ? void 0 : _member$user2.id) !== null && _member$user$id2 !== void 0 ? _member$user$id2 : member.spaceMember.user.id;
3110
3316
  }, ev.members)]);
3317
+ } else {
3318
+ var _this$members$get;
3319
+ // Reconcile into the existing (bound) collection so a reconnect
3320
+ // refetch updates it in place instead of leaving stale members.
3321
+ (_this$members$get = this.members.get(ev.id)).reconcile.apply(_this$members$get, RoomsManager_toConsumableArray(ev.members));
3111
3322
  }
3112
3323
  }
3113
3324
  }, {
3114
3325
  key: "handleSession",
3115
3326
  value: function handleSession(ev) {
3116
- this.list.deleteAll();
3117
- this.topics.deleteAll();
3118
- this.topicsPromises.forgetAll();
3119
- this.members.deleteAll();
3327
+ var stateRoomIds = new Set(ev.state.rooms.map(function (room) {
3328
+ return room.id;
3329
+ }));
3330
+
3331
+ // Remove only rooms that were left/deleted on the server during the
3332
+ // downtime, reusing the cascade cleanup (members, topics, followed
3333
+ // topics). Surviving rooms keep their identity and bindings.
3334
+ var removedRoomIds = this.list.items.filter(function (room) {
3335
+ return !stateRoomIds.has(room.id);
3336
+ }).map(function (room) {
3337
+ return room.id;
3338
+ });
3339
+ if (removedRoomIds.length) {
3340
+ this.deleteRoom.apply(this, RoomsManager_toConsumableArray(removedRoomIds));
3341
+ }
3342
+
3343
+ // Invalidate lazy caches so the next access refetches fresh data, but
3344
+ // keep the collection objects: handleRoomMembers reconciles into them,
3345
+ // so bound views refresh in place without blanking.
3120
3346
  this.membersPromises.forgetAll();
3347
+ this.topicsPromises.forgetAll();
3348
+
3349
+ // Upsert surviving/new rooms from the authoritative snapshot.
3121
3350
  this.addJoinedRooms.apply(this, RoomsManager_toConsumableArray(ev.state.rooms));
3122
3351
  this.deferredSession.resolve();
3123
3352
  }
@@ -3251,6 +3480,7 @@ function extractUserFromMember(member) {
3251
3480
  }
3252
3481
  ;// ./src/state-tracker/SpacesManager.ts
3253
3482
  function SpacesManager_typeof(o) { "@babel/helpers - typeof"; return SpacesManager_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, SpacesManager_typeof(o); }
3483
+ function SpacesManager_createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = SpacesManager_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
3254
3484
  function SpacesManager_toConsumableArray(r) { return SpacesManager_arrayWithoutHoles(r) || SpacesManager_iterableToArray(r) || SpacesManager_unsupportedIterableToArray(r) || SpacesManager_nonIterableSpread(); }
3255
3485
  function SpacesManager_nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3256
3486
  function SpacesManager_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return SpacesManager_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? SpacesManager_arrayLikeToArray(r, a) : void 0; } }
@@ -3341,8 +3571,8 @@ var SpacesManager = /*#__PURE__*/function () {
3341
3571
  });
3342
3572
  }
3343
3573
 
3344
- /**
3345
- * Get collection of all the spaces you are in.
3574
+ /**
3575
+ * Get collection of all the spaces you are in.
3346
3576
  */
3347
3577
  return SpacesManager_createClass(SpacesManager, [{
3348
3578
  key: "get",
@@ -3363,8 +3593,8 @@ var SpacesManager = /*#__PURE__*/function () {
3363
3593
  }
3364
3594
  return get;
3365
3595
  }()
3366
- /**
3367
- * Get collection of space roles.
3596
+ /**
3597
+ * Get collection of space roles.
3368
3598
  */
3369
3599
  )
3370
3600
  }, {
@@ -3386,8 +3616,8 @@ var SpacesManager = /*#__PURE__*/function () {
3386
3616
  }
3387
3617
  return getRoles;
3388
3618
  }()
3389
- /**
3390
- * Get collection of the all available rooms inside given space.
3619
+ /**
3620
+ * Get collection of the all available rooms inside given space.
3391
3621
  */
3392
3622
  )
3393
3623
  }, {
@@ -3435,8 +3665,8 @@ var SpacesManager = /*#__PURE__*/function () {
3435
3665
  }
3436
3666
  return getRooms;
3437
3667
  }()
3438
- /**
3439
- * Get collection of space members.
3668
+ /**
3669
+ * Get collection of space members.
3440
3670
  */
3441
3671
  )
3442
3672
  }, {
@@ -3484,8 +3714,8 @@ var SpacesManager = /*#__PURE__*/function () {
3484
3714
  }
3485
3715
  return getMembers;
3486
3716
  }()
3487
- /**
3488
- * Get a space member representing the current user.
3717
+ /**
3718
+ * Get a space member representing the current user.
3489
3719
  */
3490
3720
  )
3491
3721
  }, {
@@ -3654,6 +3884,11 @@ var SpacesManager = /*#__PURE__*/function () {
3654
3884
  this.members.set([ev.id, new ObservableIndexedObjectCollection(function (member) {
3655
3885
  return member === null || member === void 0 ? void 0 : member.user.id;
3656
3886
  }, ev.members)]);
3887
+ } else {
3888
+ var _this$members$get;
3889
+ // Reconcile into the existing (bound) collection so a reconnect
3890
+ // refetch updates it in place instead of leaving stale members.
3891
+ (_this$members$get = this.members.get(ev.id)).reconcile.apply(_this$members$get, SpacesManager_toConsumableArray(ev.members));
3657
3892
  }
3658
3893
  }
3659
3894
  }, {
@@ -3662,10 +3897,13 @@ var SpacesManager = /*#__PURE__*/function () {
3662
3897
  var _this4 = this;
3663
3898
  if (!this.rooms.has(ev.id)) {
3664
3899
  this.rooms.set([ev.id, new ObservableIndexedObjectCollection('id', ev.summaries)]);
3665
- ev.summaries.forEach(function (summary) {
3666
- return _this4.roomIdToSpaceId.set([summary.id, ev.id]);
3667
- });
3900
+ } else {
3901
+ var _this$rooms$get4;
3902
+ (_this$rooms$get4 = this.rooms.get(ev.id)).reconcile.apply(_this$rooms$get4, SpacesManager_toConsumableArray(ev.summaries));
3668
3903
  }
3904
+ ev.summaries.forEach(function (summary) {
3905
+ return _this4.roomIdToSpaceId.set([summary.id, ev.id]);
3906
+ });
3669
3907
  }
3670
3908
  }, {
3671
3909
  key: "handleRoomSummaryUpdated",
@@ -3677,9 +3915,9 @@ var SpacesManager = /*#__PURE__*/function () {
3677
3915
  case 0:
3678
3916
  spaceId = this.roomIdToSpaceId.get(ev.summary.id);
3679
3917
  summariesPromise = this.roomsPromises.get(spaceId);
3680
- /**
3681
- * Update summary only if the list was already loaded.
3682
- * RoomSummaryUpdated event has a partial summary, so we need to update the existing summary by merging it.
3918
+ /**
3919
+ * Update summary only if the list was already loaded.
3920
+ * RoomSummaryUpdated event has a partial summary, so we need to update the existing summary by merging it.
3683
3921
  */
3684
3922
  if (!(spaceId && summariesPromise)) {
3685
3923
  _context9.n = 2;
@@ -3733,14 +3971,58 @@ var SpacesManager = /*#__PURE__*/function () {
3733
3971
  }, {
3734
3972
  key: "handleSession",
3735
3973
  value: function handleSession(ev) {
3736
- this.list.deleteAll();
3737
- this.roles.deleteAll();
3738
- this.rooms.deleteAll();
3974
+ var _this$list2;
3975
+ var stateSpaceIds = new Set(ev.state.spaces.map(function (space) {
3976
+ return space.id;
3977
+ }));
3978
+
3979
+ // Remove only spaces that were left/deleted on the server during the
3980
+ // downtime, reusing the cascade cleanup (roles, rooms, members, index).
3981
+ var removedSpaceIds = this.list.items.filter(function (space) {
3982
+ return !stateSpaceIds.has(space.id);
3983
+ }).map(function (space) {
3984
+ return space.id;
3985
+ });
3986
+ var _iterator = SpacesManager_createForOfIteratorHelper(removedSpaceIds),
3987
+ _step;
3988
+ try {
3989
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
3990
+ var spaceId = _step.value;
3991
+ this.handleSpaceDeleted({
3992
+ id: spaceId
3993
+ });
3994
+ }
3995
+
3996
+ // Invalidate lazy caches (rooms/members) but keep their objects so the
3997
+ // next access refetches and reconciles them in place.
3998
+ } catch (err) {
3999
+ _iterator.e(err);
4000
+ } finally {
4001
+ _iterator.f();
4002
+ }
3739
4003
  this.roomsPromises.forgetAll();
3740
- this.members.deleteAll();
3741
4004
  this.membersPromises.forgetAll();
3742
- this.roomIdToSpaceId.deleteAll();
3743
- this.addJoinedSpaces.apply(this, SpacesManager_toConsumableArray(ev.state.spaces));
4005
+
4006
+ // Reconcile roles in place (kept, possibly bound object) and upsert the
4007
+ // spaces from the authoritative snapshot.
4008
+ var _iterator2 = SpacesManager_createForOfIteratorHelper(ev.state.spaces),
4009
+ _step2;
4010
+ try {
4011
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
4012
+ var space = _step2.value;
4013
+ if (this.roles.has(space.id)) {
4014
+ var _this$roles$get2;
4015
+ (_this$roles$get2 = this.roles.get(space.id)).reconcile.apply(_this$roles$get2, SpacesManager_toConsumableArray(space.roles));
4016
+ } else {
4017
+ this.roles.set([space.id, new ObservableIndexedObjectCollection('id', space.roles)]);
4018
+ }
4019
+ }
4020
+ } catch (err) {
4021
+ _iterator2.e(err);
4022
+ } finally {
4023
+ _iterator2.f();
4024
+ }
4025
+ (_this$list2 = this.list).set.apply(_this$list2, SpacesManager_toConsumableArray(ev.state.spaces));
3744
4026
  this.deferredSession.resolve();
3745
4027
  }
3746
4028
  }, {
@@ -4464,8 +4746,12 @@ var PermissionsManager = /*#__PURE__*/function (_EventTarget) {
4464
4746
  }, {
4465
4747
  key: "handleSession",
4466
4748
  value: function handleSession(ev) {
4467
- this.overwrites.deleteAll();
4749
+ // Drop the fetch guards so permission checks recompute against fresh
4750
+ // overwrites (getOverwrites refetches and upserts on the next access),
4751
+ // and notify consumers to recompute so bound permission UI is never
4752
+ // left showing stale results after a reconnect.
4468
4753
  this.overwritesPromises.forgetAll();
4754
+ this.emit('change');
4469
4755
  }
4470
4756
  }]);
4471
4757
  }(EventTarget);
@@ -4563,13 +4849,16 @@ var EmoticonsManager = /*#__PURE__*/function () {
4563
4849
  }, {
4564
4850
  key: "handleEmoticons",
4565
4851
  value: function handleEmoticons(event) {
4566
- var _event$location$space;
4852
+ var _event$location$space, _this$list$get;
4567
4853
  var spaceId = (_event$location$space = event.location.spaceId) !== null && _event$location$space !== void 0 ? _event$location$space : GLOBAL_KEY;
4568
4854
  if (!this.list.has(spaceId)) {
4569
4855
  this.list.set([spaceId, new ObservableIndexedObjectCollection('id')]);
4570
4856
  }
4571
- var collection = this.list.get(spaceId);
4572
- collection.set.apply(collection, EmoticonsManager_toConsumableArray(event.emoticons));
4857
+
4858
+ // handleEmoticons always carries the full list for a location, so
4859
+ // reconcile in place: a reconnect refetch drops removed emoticons and
4860
+ // adds new ones without blanking a bound (visible) collection.
4861
+ (_this$list$get = this.list.get(spaceId)).reconcile.apply(_this$list$get, EmoticonsManager_toConsumableArray(event.emoticons));
4573
4862
  }
4574
4863
  }, {
4575
4864
  key: "handleNewEmoticon",
@@ -4593,7 +4882,9 @@ var EmoticonsManager = /*#__PURE__*/function () {
4593
4882
  }, {
4594
4883
  key: "handleSession",
4595
4884
  value: function handleSession() {
4596
- this.list.deleteAll();
4885
+ // Keep cached emoticon collections (they may be bound to visible
4886
+ // pickers); just drop the fetch guards so the next access refetches and
4887
+ // reconciles them in place.
4597
4888
  this.emoticonsPromises.forgetAll();
4598
4889
  }
4599
4890
  }]);
@@ -4682,7 +4973,9 @@ var UsersManager = /*#__PURE__*/function () {
4682
4973
  }, {
4683
4974
  key: "handleSession",
4684
4975
  value: function handleSession(session) {
4685
- this.users.deleteAll();
4976
+ // Keep the "seen users" cache across reconnects so bound user lists do
4977
+ // not blank out; just ensure our own user is present/updated. Stale
4978
+ // entries are refreshed as member/message collections refetch.
4686
4979
  this.handleUsers([session.user]);
4687
4980
  }
4688
4981
  }, {
@@ -4702,6 +4995,12 @@ var UsersManager = /*#__PURE__*/function () {
4702
4995
  }();
4703
4996
  ;// ./src/state-tracker/RelationshipsManager.ts
4704
4997
  function RelationshipsManager_typeof(o) { "@babel/helpers - typeof"; return RelationshipsManager_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, RelationshipsManager_typeof(o); }
4998
+ function RelationshipsManager_toConsumableArray(r) { return RelationshipsManager_arrayWithoutHoles(r) || RelationshipsManager_iterableToArray(r) || RelationshipsManager_unsupportedIterableToArray(r) || RelationshipsManager_nonIterableSpread(); }
4999
+ function RelationshipsManager_nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5000
+ function RelationshipsManager_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return RelationshipsManager_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? RelationshipsManager_arrayLikeToArray(r, a) : void 0; } }
5001
+ function RelationshipsManager_iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
5002
+ function RelationshipsManager_arrayWithoutHoles(r) { if (Array.isArray(r)) return RelationshipsManager_arrayLikeToArray(r); }
5003
+ function RelationshipsManager_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4705
5004
  function RelationshipsManager_regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return RelationshipsManager_regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (RelationshipsManager_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, RelationshipsManager_regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, RelationshipsManager_regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), RelationshipsManager_regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", RelationshipsManager_regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), RelationshipsManager_regeneratorDefine2(u), RelationshipsManager_regeneratorDefine2(u, o, "Generator"), RelationshipsManager_regeneratorDefine2(u, n, function () { return this; }), RelationshipsManager_regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (RelationshipsManager_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
4706
5005
  function RelationshipsManager_regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } RelationshipsManager_regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { RelationshipsManager_regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, RelationshipsManager_regeneratorDefine2(e, r, n, t); }
4707
5006
  function RelationshipsManager_asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
@@ -4803,11 +5102,10 @@ var RelationshipsManager = /*#__PURE__*/function () {
4803
5102
  }, {
4804
5103
  key: "handleRelationships",
4805
5104
  value: function handleRelationships(ev) {
4806
- var _this3 = this;
4807
- this.relationships.deleteAll();
4808
- ev.relationships.forEach(function (relationship) {
4809
- _this3.relationships.set(relationship);
4810
- });
5105
+ var _this$relationships;
5106
+ // Full list from the server: reconcile in place so a reconnect refetch
5107
+ // updates a bound (visible) list without an intermediate empty state.
5108
+ (_this$relationships = this.relationships).reconcile.apply(_this$relationships, RelationshipsManager_toConsumableArray(ev.relationships));
4811
5109
  }
4812
5110
  }, {
4813
5111
  key: "handleNewRelationship",
@@ -4826,8 +5124,9 @@ var RelationshipsManager = /*#__PURE__*/function () {
4826
5124
  }, {
4827
5125
  key: "handleSession",
4828
5126
  value: function handleSession() {
5127
+ // Keep the (possibly bound) collection; just drop the fetch guard so the
5128
+ // next get() refetches and reconciles it in place.
4829
5129
  this.promises.forgetAll();
4830
- this.relationships.deleteAll();
4831
5130
  }
4832
5131
  }]);
4833
5132
  }();