@liveblocks/react 2.15.0-debug1 → 2.15.0

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.
@@ -196,14 +196,14 @@ var use = (
196
196
  // src/umbrella-store.ts
197
197
  import {
198
198
  autoRetry,
199
- batch,
199
+ batch as batch2,
200
200
  compactObject,
201
201
  console as console2,
202
202
  DerivedSignal,
203
203
  HttpError,
204
204
  kInternal,
205
205
  makeEventSource,
206
- mapValues,
206
+ MutableSignal as MutableSignal2,
207
207
  nanoid,
208
208
  nn,
209
209
  Signal,
@@ -227,8 +227,16 @@ function autobind(self) {
227
227
  } while ((obj = Reflect.getPrototypeOf(obj)) && obj !== Object.prototype);
228
228
  }
229
229
 
230
+ // src/lib/itertools.ts
231
+ function find(it, predicate) {
232
+ for (const item of it) {
233
+ if (predicate(item)) return item;
234
+ }
235
+ return void 0;
236
+ }
237
+
230
238
  // src/ThreadDB.ts
231
- import { MutableSignal, SortedList } from "@liveblocks/core";
239
+ import { batch, MutableSignal, SortedList } from "@liveblocks/core";
232
240
 
233
241
  // src/lib/guards.ts
234
242
  import { isPlainObject as isPlainObject2 } from "@liveblocks/core";
@@ -346,6 +354,18 @@ var ThreadDB = class _ThreadDB {
346
354
  this.upsert(thread);
347
355
  }
348
356
  }
357
+ applyDelta(updates) {
358
+ batch(() => {
359
+ for (const thread of updates.newThreads) {
360
+ this.upsertIfNewer(thread);
361
+ }
362
+ for (const { id, deletedAt } of updates.deletedThreads) {
363
+ const existing = this.getEvenIfDeleted(id);
364
+ if (!existing) continue;
365
+ this.delete(id, deletedAt);
366
+ }
367
+ });
368
+ }
349
369
  /**
350
370
  * Marks a thread as deleted. It will no longer pop up in .findMany()
351
371
  * queries, but it can still be accessed via `.getEvenIfDeleted()`.
@@ -533,14 +553,11 @@ var SinglePageResource = class {
533
553
  const usable = this.#cachedPromise;
534
554
  if (usable === null || usable.status === "pending") {
535
555
  return ASYNC_LOADING;
536
- }
537
- if (usable.status === "rejected") {
556
+ } else if (usable.status === "rejected") {
538
557
  return { isLoading: false, error: usable.reason };
558
+ } else {
559
+ return { isLoading: false, data: void 0 };
539
560
  }
540
- return {
541
- isLoading: false,
542
- data: void 0
543
- };
544
561
  }
545
562
  #cachedPromise = null;
546
563
  waitUntilLoaded() {
@@ -567,9 +584,164 @@ var SinglePageResource = class {
567
584
  return promise;
568
585
  }
569
586
  };
587
+ function createStore_forNotifications() {
588
+ const signal = new MutableSignal2(/* @__PURE__ */ new Map());
589
+ function markRead(notificationId, readAt) {
590
+ signal.mutate((lut) => {
591
+ const existing = lut.get(notificationId);
592
+ if (!existing) {
593
+ return false;
594
+ }
595
+ lut.set(notificationId, { ...existing, readAt });
596
+ return true;
597
+ });
598
+ }
599
+ function markAllRead(readAt) {
600
+ return signal.mutate((lut) => {
601
+ for (const n of lut.values()) {
602
+ n.readAt = readAt;
603
+ }
604
+ });
605
+ }
606
+ function deleteOne(inboxNotificationId) {
607
+ signal.mutate((lut) => lut.delete(inboxNotificationId));
608
+ }
609
+ function clear() {
610
+ signal.mutate((lut) => lut.clear());
611
+ }
612
+ function applyDelta(newInboxNotifications, deletedNotifications) {
613
+ signal.mutate((lut) => {
614
+ let mutated = false;
615
+ for (const n of newInboxNotifications) {
616
+ const existing = lut.get(n.id);
617
+ if (existing) {
618
+ const result = compareInboxNotifications(existing, n);
619
+ if (result === 1) continue;
620
+ }
621
+ lut.set(n.id, n);
622
+ mutated = true;
623
+ }
624
+ for (const n of deletedNotifications) {
625
+ lut.delete(n.id);
626
+ mutated = true;
627
+ }
628
+ return mutated;
629
+ });
630
+ }
631
+ function updateAssociatedNotification(newComment) {
632
+ signal.mutate((lut) => {
633
+ const existing = find(
634
+ lut.values(),
635
+ (notification) => notification.kind === "thread" && notification.threadId === newComment.threadId
636
+ );
637
+ if (!existing) return false;
638
+ lut.set(existing.id, {
639
+ ...existing,
640
+ notifiedAt: newComment.createdAt,
641
+ readAt: newComment.createdAt
642
+ });
643
+ return true;
644
+ });
645
+ }
646
+ return {
647
+ signal: signal.asReadonly(),
648
+ // Mutations
649
+ markAllRead,
650
+ markRead,
651
+ delete: deleteOne,
652
+ applyDelta,
653
+ clear,
654
+ updateAssociatedNotification,
655
+ // XXX_vincent Remove this eventually
656
+ force_set: (mutationCallback) => signal.mutate(mutationCallback),
657
+ invalidate: () => signal.mutate()
658
+ };
659
+ }
660
+ function createStore_forRoomNotificationSettings() {
661
+ const signal = new MutableSignal2(/* @__PURE__ */ new Map());
662
+ function update(roomId, settings) {
663
+ signal.mutate((lut) => {
664
+ lut.set(roomId, settings);
665
+ });
666
+ }
667
+ return {
668
+ signal: signal.asReadonly(),
669
+ // Mutations
670
+ update,
671
+ // XXX_vincent Remove this eventually
672
+ invalidate: () => signal.mutate()
673
+ };
674
+ }
675
+ function createStore_forHistoryVersions() {
676
+ const signal = new MutableSignal2(/* @__PURE__ */ new Map());
677
+ function update(roomId, versions) {
678
+ signal.mutate((lut) => {
679
+ const versionsById = lut.get(roomId) ?? (lut.set(roomId, /* @__PURE__ */ new Map()), lut.get(roomId));
680
+ for (const version of versions) {
681
+ versionsById.set(version.id, version);
682
+ }
683
+ });
684
+ }
685
+ return {
686
+ signal: signal.asReadonly(),
687
+ // Mutations
688
+ update,
689
+ // XXX_vincent Remove these eventually
690
+ force_set: (callback) => signal.mutate(callback),
691
+ invalidate: () => signal.mutate()
692
+ };
693
+ }
694
+ function createStore_forPermissionHints() {
695
+ const signal = new Signal({});
696
+ function update(newHints) {
697
+ signal.set((prev) => {
698
+ const permissionsByRoom = { ...prev };
699
+ for (const [roomId, newPermissions] of Object.entries(newHints)) {
700
+ const existing = permissionsByRoom[roomId] ?? /* @__PURE__ */ new Set();
701
+ for (const permission of newPermissions) {
702
+ existing.add(permission);
703
+ }
704
+ permissionsByRoom[roomId] = existing;
705
+ }
706
+ return permissionsByRoom;
707
+ });
708
+ }
709
+ return {
710
+ signal: signal.asReadonly(),
711
+ // Mutations
712
+ update,
713
+ // XXX_vincent Remove this eventually
714
+ invalidate: () => signal.set((store) => ({ ...store }))
715
+ };
716
+ }
717
+ function createStore_forOptimistic(client) {
718
+ const signal = new Signal([]);
719
+ const syncSource = client[kInternal].createSyncSource();
720
+ signal.subscribe(
721
+ () => syncSource.setSyncStatus(
722
+ signal.get().length > 0 ? "synchronizing" : "synchronized"
723
+ )
724
+ );
725
+ function add(optimisticUpdate) {
726
+ const id = nanoid();
727
+ const newUpdate = { ...optimisticUpdate, id };
728
+ signal.set((state) => [...state, newUpdate]);
729
+ return id;
730
+ }
731
+ function remove(optimisticId) {
732
+ signal.set((state) => state.filter((ou) => ou.id !== optimisticId));
733
+ }
734
+ return {
735
+ signal: signal.asReadonly(),
736
+ // Mutations
737
+ add,
738
+ remove,
739
+ // XXX_vincent Remove this eventually
740
+ invalidate: () => signal.set((store) => [...store])
741
+ };
742
+ }
570
743
  var UmbrellaStore = class {
571
744
  #client;
572
- #syncSource;
573
745
  //
574
746
  // Internally, the UmbrellaStore keeps track of a few source signals that can
575
747
  // be set and mutated individually. When any of those are mutated then the
@@ -596,13 +768,17 @@ var UmbrellaStore = class {
596
768
  // Input signals.
597
769
  // (Can be mutated directly.)
598
770
  //
599
- baseThreadsDB;
771
+ // XXX_vincent Now that we have createStore_forX, we should probably also change
772
+ // `threads` to this pattern, ie create a createStore_forThreads helper as
773
+ // well. It almost works like that already anyway!
774
+ threads;
600
775
  // Exposes its signal under `.signal` prop
601
- baseNotificationsById;
602
- baseSettingsByRoomId;
776
+ notifications;
777
+ roomNotificationSettings;
778
+ // prettier-ignore
779
+ historyVersions;
780
+ permissionHints;
603
781
  optimisticUpdates;
604
- baseVersionsByRoomId;
605
- permissionHintsByRoomId;
606
782
  //
607
783
  // Output signals.
608
784
  // (Readonly, clean, consistent. With optimistic updates applied.)
@@ -611,7 +787,7 @@ var UmbrellaStore = class {
611
787
  // threads and notifications separately, but the threadifications signal will
612
788
  // be updated whenever either of them change.
613
789
  //
614
- // TODO(vincent+nimesh) APIs like getRoomThreadsLoadingState should really also be modeled as output signals.
790
+ // XXX_vincent APIs like getRoomThreadsLoadingState should really also be modeled as output signals.
615
791
  //
616
792
  outputs;
617
793
  // Notifications
@@ -631,13 +807,11 @@ var UmbrellaStore = class {
631
807
  #roomNotificationSettings = /* @__PURE__ */ new Map();
632
808
  constructor(client) {
633
809
  this.#client = client[kInternal].as();
634
- this.#syncSource = this.#client[kInternal].createSyncSource();
810
+ this.optimisticUpdates = createStore_forOptimistic(this.#client);
811
+ this.permissionHints = createStore_forPermissionHints();
635
812
  const inboxFetcher = async (cursor) => {
636
813
  const result = await this.#client.getInboxNotifications({ cursor });
637
- this.updateThreadsAndNotifications(
638
- result.threads,
639
- result.inboxNotifications
640
- );
814
+ this.updateThreadifications(result.threads, result.inboxNotifications);
641
815
  if (this.#notificationsLastRequestedAt === null) {
642
816
  this.#notificationsLastRequestedAt = result.requestedAt;
643
817
  }
@@ -652,16 +826,14 @@ var UmbrellaStore = class {
652
826
  this.invalidateEntireStore()
653
827
  )
654
828
  );
655
- this.baseThreadsDB = new ThreadDB();
656
- this.optimisticUpdates = new Signal([]);
657
- this.baseVersionsByRoomId = new Signal({});
658
- this.baseNotificationsById = new Signal({});
659
- this.baseSettingsByRoomId = new Signal({});
660
- this.permissionHintsByRoomId = new Signal({});
829
+ this.threads = new ThreadDB();
830
+ this.notifications = createStore_forNotifications();
831
+ this.roomNotificationSettings = createStore_forRoomNotificationSettings();
832
+ this.historyVersions = createStore_forHistoryVersions();
661
833
  const threadifications = DerivedSignal.from(
662
- this.baseThreadsDB.signal,
663
- this.baseNotificationsById,
664
- this.optimisticUpdates,
834
+ this.threads.signal,
835
+ this.notifications.signal,
836
+ this.optimisticUpdates.signal,
665
837
  (ts, ns, updates) => applyOptimisticUpdates_forThreadifications(ts, ns, updates)
666
838
  );
667
839
  const threads = DerivedSignal.from(threadifications, (s) => ({
@@ -672,13 +844,18 @@ var UmbrellaStore = class {
672
844
  notificationsById: s.notificationsById
673
845
  }));
674
846
  const settingsByRoomId = DerivedSignal.from(
675
- this.baseSettingsByRoomId,
676
- this.optimisticUpdates,
847
+ this.roomNotificationSettings.signal,
848
+ this.optimisticUpdates.signal,
677
849
  (settings, updates) => applyOptimisticUpdates_forSettings(settings, updates)
678
850
  );
679
851
  const versionsByRoomId = DerivedSignal.from(
680
- this.baseVersionsByRoomId,
681
- (hv) => hv
852
+ this.historyVersions.signal,
853
+ (hv) => Object.fromEntries(
854
+ [...hv].map(([roomId, versions]) => [
855
+ roomId,
856
+ Object.fromEntries(versions)
857
+ ])
858
+ )
682
859
  );
683
860
  this.outputs = {
684
861
  threadifications,
@@ -687,11 +864,6 @@ var UmbrellaStore = class {
687
864
  settingsByRoomId,
688
865
  versionsByRoomId
689
866
  };
690
- this.optimisticUpdates.subscribe(
691
- () => this.#syncSource.setSyncStatus(
692
- this.optimisticUpdates.get().length > 0 ? "synchronizing" : "synchronized"
693
- )
694
- );
695
867
  autobind(this);
696
868
  }
697
869
  get1_both() {
@@ -797,7 +969,7 @@ var UmbrellaStore = class {
797
969
  };
798
970
  }
799
971
  // NOTE: This will read the async result, but WILL NOT start loading at the moment!
800
- // TODO(vincent+nimesh) This should really be a derived Signal!
972
+ // XXX_vincent This should really be a derived Signal!
801
973
  getNotificationSettingsLoadingState(roomId) {
802
974
  const queryKey = makeNotificationSettingsQueryKey(roomId);
803
975
  const resource = this.#roomNotificationSettings.get(queryKey);
@@ -828,48 +1000,17 @@ var UmbrellaStore = class {
828
1000
  versions: Object.values(this.get3()[roomId] ?? {})
829
1001
  };
830
1002
  }
831
- // Direct low-level cache mutations ------------------------------------------------- {{{
832
- #mutateThreadsDB(mutate) {
833
- batch(() => {
834
- mutate(this.baseThreadsDB);
835
- });
836
- }
837
- #updateInboxNotificationsCache(mapFn) {
838
- this.baseNotificationsById.set((prev) => mapFn(prev));
839
- }
840
- #setNotificationSettings(roomId, settings) {
841
- this.baseSettingsByRoomId.set((state) => ({
842
- ...state,
843
- [roomId]: settings
844
- }));
845
- }
846
- #updateRoomVersions(roomId, versions) {
847
- this.baseVersionsByRoomId.set((prev) => {
848
- const newVersions = { ...prev[roomId] };
849
- for (const version of versions) {
850
- newVersions[version.id] = version;
851
- }
852
- return {
853
- ...prev,
854
- [roomId]: newVersions
855
- };
856
- });
857
- }
858
- #updateOptimisticUpdatesCache(mapFn) {
859
- this.optimisticUpdates.set(mapFn);
860
- }
861
- // ---------------------------------------------------------------------------------- }}}
862
1003
  /** @internal - Only call this method from unit tests. */
863
1004
  force_set_versions(callback) {
864
- batch(() => {
865
- this.baseVersionsByRoomId.set(callback);
1005
+ batch2(() => {
1006
+ this.historyVersions.force_set(callback);
866
1007
  this.invalidateEntireStore();
867
1008
  });
868
1009
  }
869
1010
  /** @internal - Only call this method from unit tests. */
870
1011
  force_set_notifications(callback) {
871
- batch(() => {
872
- this.baseNotificationsById.set(callback);
1012
+ batch2(() => {
1013
+ this.notifications.force_set(callback);
873
1014
  this.invalidateEntireStore();
874
1015
  });
875
1016
  }
@@ -877,64 +1018,47 @@ var UmbrellaStore = class {
877
1018
  * Updates an existing inbox notification with a new value, replacing the
878
1019
  * corresponding optimistic update.
879
1020
  *
880
- * This will not update anything if the inbox notification ID isn't found in
881
- * the cache.
1021
+ * This will not update anything if the inbox notification ID isn't found.
882
1022
  */
883
- updateInboxNotification(inboxNotificationId, optimisticUpdateId, callback) {
884
- batch(() => {
885
- this.removeOptimisticUpdate(optimisticUpdateId);
886
- this.#updateInboxNotificationsCache((cache) => {
887
- const existing = cache[inboxNotificationId];
888
- if (!existing) {
889
- return cache;
890
- }
891
- return {
892
- ...cache,
893
- [inboxNotificationId]: callback(existing)
894
- };
895
- });
1023
+ markInboxNotificationRead(inboxNotificationId, readAt, optimisticId) {
1024
+ batch2(() => {
1025
+ this.optimisticUpdates.remove(optimisticId);
1026
+ this.notifications.markRead(inboxNotificationId, readAt);
896
1027
  });
897
1028
  }
898
- /**
899
- * Updates *all* inbox notifications by running a mapper function over all of
900
- * them, replacing the corresponding optimistic update.
901
- */
902
- updateAllInboxNotifications(optimisticUpdateId, mapFn) {
903
- batch(() => {
904
- this.removeOptimisticUpdate(optimisticUpdateId);
905
- this.#updateInboxNotificationsCache((cache) => mapValues(cache, mapFn));
1029
+ markAllInboxNotificationsRead(optimisticId, readAt) {
1030
+ batch2(() => {
1031
+ this.optimisticUpdates.remove(optimisticId);
1032
+ this.notifications.markAllRead(readAt);
906
1033
  });
907
1034
  }
908
1035
  /**
909
1036
  * Deletes an existing inbox notification, replacing the corresponding
910
1037
  * optimistic update.
911
1038
  */
912
- deleteInboxNotification(inboxNotificationId, optimisticUpdateId) {
913
- batch(() => {
914
- this.removeOptimisticUpdate(optimisticUpdateId);
915
- this.#updateInboxNotificationsCache((cache) => {
916
- const { [inboxNotificationId]: removed, ...newCache } = cache;
917
- return removed === void 0 ? cache : newCache;
918
- });
1039
+ deleteInboxNotification(inboxNotificationId, optimisticId) {
1040
+ batch2(() => {
1041
+ this.optimisticUpdates.remove(optimisticId);
1042
+ this.notifications.delete(inboxNotificationId);
919
1043
  });
920
1044
  }
921
1045
  /**
922
1046
  * Deletes *all* inbox notifications, replacing the corresponding optimistic
923
1047
  * update.
924
1048
  */
925
- deleteAllInboxNotifications(optimisticUpdateId) {
926
- batch(() => {
927
- this.removeOptimisticUpdate(optimisticUpdateId);
928
- this.#updateInboxNotificationsCache(() => ({}));
1049
+ deleteAllInboxNotifications(optimisticId) {
1050
+ batch2(() => {
1051
+ this.optimisticUpdates.remove(optimisticId);
1052
+ this.notifications.clear();
929
1053
  });
930
1054
  }
931
1055
  /**
932
1056
  * Creates an new thread, replacing the corresponding optimistic update.
933
1057
  */
934
- createThread(optimisticUpdateId, thread) {
935
- batch(() => {
936
- this.removeOptimisticUpdate(optimisticUpdateId);
937
- this.#mutateThreadsDB((db) => db.upsert(thread));
1058
+ createThread(optimisticId, thread) {
1059
+ batch2(() => {
1060
+ this.optimisticUpdates.remove(optimisticId);
1061
+ this.threads.upsert(thread);
938
1062
  });
939
1063
  }
940
1064
  /**
@@ -942,44 +1066,43 @@ var UmbrellaStore = class {
942
1066
  * optimistic update.
943
1067
  *
944
1068
  * This will not update anything if:
945
- * - The thread ID isn't found in the cache; or
946
- * - The thread ID was already deleted from the cache; or
947
- * - The thread ID in the cache was updated more recently than the optimistic
948
- * update's timestamp (if given)
1069
+ * - The thread ID isn't found; or
1070
+ * - The thread ID was already deleted; or
1071
+ * - The thread ID was updated more recently than the optimistic update's
1072
+ * timestamp (if given)
949
1073
  */
950
- #updateThread(threadId, optimisticUpdateId, callback, updatedAt) {
951
- batch(() => {
952
- if (optimisticUpdateId !== null) {
953
- this.removeOptimisticUpdate(optimisticUpdateId);
1074
+ #updateThread(threadId, optimisticId, callback, updatedAt) {
1075
+ batch2(() => {
1076
+ if (optimisticId !== null) {
1077
+ this.optimisticUpdates.remove(optimisticId);
954
1078
  }
955
- this.#mutateThreadsDB((db) => {
956
- const existing = db.get(threadId);
957
- if (!existing) return;
958
- if (!!updatedAt && existing.updatedAt > updatedAt) return;
959
- db.upsert(callback(existing));
960
- });
1079
+ const db = this.threads;
1080
+ const existing = db.get(threadId);
1081
+ if (!existing) return;
1082
+ if (!!updatedAt && existing.updatedAt > updatedAt) return;
1083
+ db.upsert(callback(existing));
961
1084
  });
962
1085
  }
963
- patchThread(threadId, optimisticUpdateId, patch, updatedAt) {
1086
+ patchThread(threadId, optimisticId, patch, updatedAt) {
964
1087
  return this.#updateThread(
965
1088
  threadId,
966
- optimisticUpdateId,
1089
+ optimisticId,
967
1090
  (thread) => ({ ...thread, ...compactObject(patch) }),
968
1091
  updatedAt
969
1092
  );
970
1093
  }
971
- addReaction(threadId, optimisticUpdateId, commentId, reaction, createdAt) {
1094
+ addReaction(threadId, optimisticId, commentId, reaction, createdAt) {
972
1095
  this.#updateThread(
973
1096
  threadId,
974
- optimisticUpdateId,
1097
+ optimisticId,
975
1098
  (thread) => applyAddReaction(thread, commentId, reaction),
976
1099
  createdAt
977
1100
  );
978
1101
  }
979
- removeReaction(threadId, optimisticUpdateId, commentId, emoji, userId, removedAt) {
1102
+ removeReaction(threadId, optimisticId, commentId, emoji, userId, removedAt) {
980
1103
  this.#updateThread(
981
1104
  threadId,
982
- optimisticUpdateId,
1105
+ optimisticId,
983
1106
  (thread) => applyRemoveReaction(thread, commentId, emoji, userId, removedAt),
984
1107
  removedAt
985
1108
  );
@@ -989,13 +1112,13 @@ var UmbrellaStore = class {
989
1112
  * replacing the corresponding optimistic update.
990
1113
  *
991
1114
  * This will not update anything if:
992
- * - The thread ID isn't found in the cache; or
993
- * - The thread ID was already deleted from the cache
1115
+ * - The thread ID isn't found; or
1116
+ * - The thread ID was already deleted
994
1117
  */
995
- deleteThread(threadId, optimisticUpdateId) {
1118
+ deleteThread(threadId, optimisticId) {
996
1119
  return this.#updateThread(
997
1120
  threadId,
998
- optimisticUpdateId,
1121
+ optimisticId,
999
1122
  // A deletion is actually an update of the deletedAt property internally
1000
1123
  (thread) => ({ ...thread, updatedAt: /* @__PURE__ */ new Date(), deletedAt: /* @__PURE__ */ new Date() })
1001
1124
  );
@@ -1004,94 +1127,48 @@ var UmbrellaStore = class {
1004
1127
  * Creates an existing comment and ensures the associated notification is
1005
1128
  * updated correctly, replacing the corresponding optimistic update.
1006
1129
  */
1007
- createComment(newComment, optimisticUpdateId) {
1008
- batch(() => {
1009
- this.removeOptimisticUpdate(optimisticUpdateId);
1010
- const existingThread = this.baseThreadsDB.get(newComment.threadId);
1130
+ createComment(newComment, optimisticId) {
1131
+ batch2(() => {
1132
+ this.optimisticUpdates.remove(optimisticId);
1133
+ const existingThread = this.threads.get(newComment.threadId);
1011
1134
  if (!existingThread) {
1012
1135
  return;
1013
1136
  }
1014
- this.#mutateThreadsDB(
1015
- (db) => db.upsert(applyUpsertComment(existingThread, newComment))
1016
- );
1017
- this.#updateInboxNotificationsCache((cache) => {
1018
- const existingNotification = Object.values(cache).find(
1019
- (notification) => notification.kind === "thread" && notification.threadId === newComment.threadId
1020
- );
1021
- if (!existingNotification) {
1022
- return cache;
1023
- }
1024
- return {
1025
- ...cache,
1026
- [existingNotification.id]: {
1027
- ...existingNotification,
1028
- notifiedAt: newComment.createdAt,
1029
- readAt: newComment.createdAt
1030
- }
1031
- };
1032
- });
1137
+ this.threads.upsert(applyUpsertComment(existingThread, newComment));
1138
+ this.notifications.updateAssociatedNotification(newComment);
1033
1139
  });
1034
1140
  }
1035
- editComment(threadId, optimisticUpdateId, editedComment) {
1141
+ editComment(threadId, optimisticId, editedComment) {
1036
1142
  return this.#updateThread(
1037
1143
  threadId,
1038
- optimisticUpdateId,
1144
+ optimisticId,
1039
1145
  (thread) => applyUpsertComment(thread, editedComment)
1040
1146
  );
1041
1147
  }
1042
- deleteComment(threadId, optimisticUpdateId, commentId, deletedAt) {
1148
+ deleteComment(threadId, optimisticId, commentId, deletedAt) {
1043
1149
  return this.#updateThread(
1044
1150
  threadId,
1045
- optimisticUpdateId,
1151
+ optimisticId,
1046
1152
  (thread) => applyDeleteComment(thread, commentId, deletedAt),
1047
1153
  deletedAt
1048
1154
  );
1049
1155
  }
1050
- updateThreadAndNotification(thread, inboxNotification) {
1051
- batch(() => {
1052
- this.#mutateThreadsDB((db) => db.upsertIfNewer(thread));
1053
- if (inboxNotification !== void 0) {
1054
- this.#updateInboxNotificationsCache((cache) => ({
1055
- ...cache,
1056
- [inboxNotification.id]: inboxNotification
1057
- }));
1058
- }
1059
- });
1060
- }
1061
- updateThreadsAndNotifications(threads, inboxNotifications, deletedThreads = [], deletedInboxNotifications = []) {
1062
- batch(() => {
1063
- this.#mutateThreadsDB(
1064
- (db) => applyThreadDeltaUpdates(db, { newThreads: threads, deletedThreads })
1065
- );
1066
- this.#updateInboxNotificationsCache(
1067
- (cache) => applyNotificationsUpdates(cache, {
1068
- newInboxNotifications: inboxNotifications,
1069
- deletedNotifications: deletedInboxNotifications
1070
- })
1071
- );
1156
+ updateThreadifications(threads, notifications, deletedThreads = [], deletedNotifications = []) {
1157
+ batch2(() => {
1158
+ this.threads.applyDelta({ newThreads: threads, deletedThreads });
1159
+ this.notifications.applyDelta(notifications, deletedNotifications);
1072
1160
  });
1073
1161
  }
1074
1162
  /**
1075
1163
  * Updates existing notification setting for a room with a new value,
1076
1164
  * replacing the corresponding optimistic update.
1077
1165
  */
1078
- updateRoomNotificationSettings_confirmOptimisticUpdate(roomId, optimisticUpdateId, settings) {
1079
- batch(() => {
1080
- this.removeOptimisticUpdate(optimisticUpdateId);
1081
- this.#setNotificationSettings(roomId, settings);
1166
+ updateRoomNotificationSettings(roomId, optimisticId, settings) {
1167
+ batch2(() => {
1168
+ this.optimisticUpdates.remove(optimisticId);
1169
+ this.roomNotificationSettings.update(roomId, settings);
1082
1170
  });
1083
1171
  }
1084
- addOptimisticUpdate(optimisticUpdate) {
1085
- const id = nanoid();
1086
- const newUpdate = { ...optimisticUpdate, id };
1087
- this.#updateOptimisticUpdatesCache((cache) => [...cache, newUpdate]);
1088
- return id;
1089
- }
1090
- removeOptimisticUpdate(optimisticUpdateId) {
1091
- this.#updateOptimisticUpdatesCache(
1092
- (cache) => cache.filter((ou) => ou.id !== optimisticUpdateId)
1093
- );
1094
- }
1095
1172
  async fetchNotificationsDeltaUpdate(signal) {
1096
1173
  const lastRequestedAt = this.#notificationsLastRequestedAt;
1097
1174
  if (lastRequestedAt === null) {
@@ -1104,7 +1181,7 @@ var UmbrellaStore = class {
1104
1181
  if (lastRequestedAt < result.requestedAt) {
1105
1182
  this.#notificationsLastRequestedAt = result.requestedAt;
1106
1183
  }
1107
- this.updateThreadsAndNotifications(
1184
+ this.updateThreadifications(
1108
1185
  result.threads.updated,
1109
1186
  result.inboxNotifications.updated,
1110
1187
  result.threads.deleted,
@@ -1114,19 +1191,6 @@ var UmbrellaStore = class {
1114
1191
  waitUntilNotificationsLoaded() {
1115
1192
  return this.#notifications.waitUntilLoaded();
1116
1193
  }
1117
- #updatePermissionHints(newHints) {
1118
- this.permissionHintsByRoomId.set((prev) => {
1119
- const permissionsByRoom = { ...prev };
1120
- for (const [roomId, newPermissions] of Object.entries(newHints)) {
1121
- const existing = permissionsByRoom[roomId] ?? /* @__PURE__ */ new Set();
1122
- for (const permission of newPermissions) {
1123
- existing.add(permission);
1124
- }
1125
- permissionsByRoom[roomId] = existing;
1126
- }
1127
- return permissionsByRoom;
1128
- });
1129
- }
1130
1194
  waitUntilRoomThreadsLoaded(roomId, query) {
1131
1195
  const threadsFetcher = async (cursor) => {
1132
1196
  const result = await this.#client[kInternal].httpClient.getThreads({
@@ -1134,11 +1198,8 @@ var UmbrellaStore = class {
1134
1198
  cursor,
1135
1199
  query
1136
1200
  });
1137
- this.updateThreadsAndNotifications(
1138
- result.threads,
1139
- result.inboxNotifications
1140
- );
1141
- this.#updatePermissionHints(result.permissionHints);
1201
+ this.updateThreadifications(result.threads, result.inboxNotifications);
1202
+ this.permissionHints.update(result.permissionHints);
1142
1203
  const lastRequestedAt = this.#roomThreadsLastRequestedAtByRoom.get(roomId);
1143
1204
  if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
1144
1205
  this.#roomThreadsLastRequestedAtByRoom.set(roomId, result.requestedAt);
@@ -1170,13 +1231,13 @@ var UmbrellaStore = class {
1170
1231
  since: lastRequestedAt,
1171
1232
  signal
1172
1233
  });
1173
- this.updateThreadsAndNotifications(
1234
+ this.updateThreadifications(
1174
1235
  updates.threads.updated,
1175
1236
  updates.inboxNotifications.updated,
1176
1237
  updates.threads.deleted,
1177
1238
  updates.inboxNotifications.deleted
1178
1239
  );
1179
- this.#updatePermissionHints(updates.permissionHints);
1240
+ this.permissionHints.update(updates.permissionHints);
1180
1241
  if (lastRequestedAt < updates.requestedAt) {
1181
1242
  this.#roomThreadsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
1182
1243
  }
@@ -1188,11 +1249,8 @@ var UmbrellaStore = class {
1188
1249
  cursor,
1189
1250
  query
1190
1251
  });
1191
- this.updateThreadsAndNotifications(
1192
- result.threads,
1193
- result.inboxNotifications
1194
- );
1195
- this.#updatePermissionHints(result.permissionHints);
1252
+ this.updateThreadifications(result.threads, result.inboxNotifications);
1253
+ this.permissionHints.update(result.permissionHints);
1196
1254
  if (this.#userThreadsLastRequestedAt === null) {
1197
1255
  this.#userThreadsLastRequestedAt = result.requestedAt;
1198
1256
  }
@@ -1212,15 +1270,15 @@ var UmbrellaStore = class {
1212
1270
  this.#userThreads.set(queryKey, paginatedResource);
1213
1271
  return paginatedResource.waitUntilLoaded();
1214
1272
  }
1215
- // TODO(vincent+nimesh) We should really be going over all call sites, and replace this call
1273
+ // XXX_vincent We should really be going over all call sites, and replace this call
1216
1274
  // with a more specific invalidation!
1217
1275
  invalidateEntireStore() {
1218
- batch(() => {
1219
- this.baseVersionsByRoomId.set((store) => ({ ...store }));
1220
- this.baseNotificationsById.set((store) => ({ ...store }));
1221
- this.optimisticUpdates.set((store) => [...store]);
1222
- this.permissionHintsByRoomId.set((store) => ({ ...store }));
1223
- this.baseSettingsByRoomId.set((store) => ({ ...store }));
1276
+ batch2(() => {
1277
+ this.historyVersions.invalidate();
1278
+ this.notifications.invalidate();
1279
+ this.optimisticUpdates.invalidate();
1280
+ this.permissionHints.invalidate();
1281
+ this.roomNotificationSettings.invalidate();
1224
1282
  });
1225
1283
  }
1226
1284
  async fetchUserThreadsDeltaUpdate(signal) {
@@ -1235,13 +1293,13 @@ var UmbrellaStore = class {
1235
1293
  if (lastRequestedAt < result.requestedAt) {
1236
1294
  this.#notificationsLastRequestedAt = result.requestedAt;
1237
1295
  }
1238
- this.updateThreadsAndNotifications(
1296
+ this.updateThreadifications(
1239
1297
  result.threads.updated,
1240
1298
  result.inboxNotifications.updated,
1241
1299
  result.threads.deleted,
1242
1300
  result.inboxNotifications.deleted
1243
1301
  );
1244
- this.#updatePermissionHints(result.permissionHints);
1302
+ this.permissionHints.update(result.permissionHints);
1245
1303
  }
1246
1304
  waitUntilRoomVersionsLoaded(roomId) {
1247
1305
  const queryKey = makeVersionsQueryKey(roomId);
@@ -1256,7 +1314,7 @@ var UmbrellaStore = class {
1256
1314
  );
1257
1315
  }
1258
1316
  const result = await room[kInternal].listTextVersions();
1259
- this.#updateRoomVersions(roomId, result.versions);
1317
+ this.historyVersions.update(roomId, result.versions);
1260
1318
  const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
1261
1319
  if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
1262
1320
  this.#roomVersionsLastRequestedAtByRoom.set(
@@ -1290,7 +1348,7 @@ var UmbrellaStore = class {
1290
1348
  since: lastRequestedAt,
1291
1349
  signal
1292
1350
  });
1293
- this.#updateRoomVersions(roomId, updates.versions);
1351
+ this.historyVersions.update(roomId, updates.versions);
1294
1352
  if (lastRequestedAt < updates.requestedAt) {
1295
1353
  this.#roomVersionsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
1296
1354
  }
@@ -1308,7 +1366,7 @@ var UmbrellaStore = class {
1308
1366
  );
1309
1367
  }
1310
1368
  const result = await room.getNotificationSettings();
1311
- this.#setNotificationSettings(roomId, result);
1369
+ this.roomNotificationSettings.update(roomId, result);
1312
1370
  };
1313
1371
  resource = new SinglePageResource(notificationSettingsFetcher);
1314
1372
  }
@@ -1328,12 +1386,12 @@ var UmbrellaStore = class {
1328
1386
  `Room with id ${roomId} is not available on client`
1329
1387
  );
1330
1388
  const result = await room.getNotificationSettings({ signal });
1331
- this.#setNotificationSettings(roomId, result);
1389
+ this.roomNotificationSettings.update(roomId, result);
1332
1390
  }
1333
1391
  };
1334
- function applyOptimisticUpdates_forThreadifications(baseThreadsDB, rawNotificationsById, optimisticUpdates) {
1392
+ function applyOptimisticUpdates_forThreadifications(baseThreadsDB, notificationsLUT, optimisticUpdates) {
1335
1393
  const threadsDB = baseThreadsDB.clone();
1336
- let notificationsById = { ...rawNotificationsById };
1394
+ let notificationsById = Object.fromEntries(notificationsLUT);
1337
1395
  for (const optimisticUpdate of optimisticUpdates) {
1338
1396
  switch (optimisticUpdate.type) {
1339
1397
  case "create-thread": {
@@ -1486,8 +1544,8 @@ function applyOptimisticUpdates_forThreadifications(baseThreadsDB, rawNotificati
1486
1544
  threadsDB
1487
1545
  };
1488
1546
  }
1489
- function applyOptimisticUpdates_forSettings(baseSettingsByRoomId, optimisticUpdates) {
1490
- const settingsByRoomId = { ...baseSettingsByRoomId };
1547
+ function applyOptimisticUpdates_forSettings(settingsLUT, optimisticUpdates) {
1548
+ const settingsByRoomId = Object.fromEntries(settingsLUT);
1491
1549
  for (const optimisticUpdate of optimisticUpdates) {
1492
1550
  switch (optimisticUpdate.type) {
1493
1551
  case "update-notification-settings": {
@@ -1504,32 +1562,6 @@ function applyOptimisticUpdates_forSettings(baseSettingsByRoomId, optimisticUpda
1504
1562
  }
1505
1563
  return settingsByRoomId;
1506
1564
  }
1507
- function applyThreadDeltaUpdates(db, updates) {
1508
- updates.newThreads.forEach((thread) => db.upsertIfNewer(thread));
1509
- updates.deletedThreads.forEach(({ id, deletedAt }) => {
1510
- const existing = db.getEvenIfDeleted(id);
1511
- if (!existing) return;
1512
- db.delete(id, deletedAt);
1513
- });
1514
- }
1515
- function applyNotificationsUpdates(existingInboxNotifications, updates) {
1516
- const updatedInboxNotifications = { ...existingInboxNotifications };
1517
- updates.newInboxNotifications.forEach((notification) => {
1518
- const existingNotification = updatedInboxNotifications[notification.id];
1519
- if (existingNotification) {
1520
- const result = compareInboxNotifications(
1521
- existingNotification,
1522
- notification
1523
- );
1524
- if (result === 1) return;
1525
- }
1526
- updatedInboxNotifications[notification.id] = notification;
1527
- });
1528
- updates.deletedNotifications.forEach(
1529
- ({ id }) => delete updatedInboxNotifications[id]
1530
- );
1531
- return updatedInboxNotifications;
1532
- }
1533
1565
  function compareInboxNotifications(inboxNotificationA, inboxNotificationB) {
1534
1566
  if (inboxNotificationA.notifiedAt > inboxNotificationB.notifiedAt) {
1535
1567
  return 1;
@@ -1920,21 +1952,21 @@ function useMarkInboxNotificationAsRead_withClient(client) {
1920
1952
  (inboxNotificationId) => {
1921
1953
  const { store } = getLiveblocksExtrasForClient(client);
1922
1954
  const readAt = /* @__PURE__ */ new Date();
1923
- const optimisticUpdateId = store.addOptimisticUpdate({
1955
+ const optimisticId = store.optimisticUpdates.add({
1924
1956
  type: "mark-inbox-notification-as-read",
1925
1957
  inboxNotificationId,
1926
1958
  readAt
1927
1959
  });
1928
1960
  client.markInboxNotificationAsRead(inboxNotificationId).then(
1929
1961
  () => {
1930
- store.updateInboxNotification(
1962
+ store.markInboxNotificationRead(
1931
1963
  inboxNotificationId,
1932
- optimisticUpdateId,
1933
- (inboxNotification) => ({ ...inboxNotification, readAt })
1964
+ readAt,
1965
+ optimisticId
1934
1966
  );
1935
1967
  },
1936
1968
  () => {
1937
- store.removeOptimisticUpdate(optimisticUpdateId);
1969
+ store.optimisticUpdates.remove(optimisticId);
1938
1970
  }
1939
1971
  );
1940
1972
  },
@@ -1945,19 +1977,16 @@ function useMarkAllInboxNotificationsAsRead_withClient(client) {
1945
1977
  return useCallback2(() => {
1946
1978
  const { store } = getLiveblocksExtrasForClient(client);
1947
1979
  const readAt = /* @__PURE__ */ new Date();
1948
- const optimisticUpdateId = store.addOptimisticUpdate({
1980
+ const optimisticId = store.optimisticUpdates.add({
1949
1981
  type: "mark-all-inbox-notifications-as-read",
1950
1982
  readAt
1951
1983
  });
1952
1984
  client.markAllInboxNotificationsAsRead().then(
1953
1985
  () => {
1954
- store.updateAllInboxNotifications(
1955
- optimisticUpdateId,
1956
- (inboxNotification) => ({ ...inboxNotification, readAt })
1957
- );
1986
+ store.markAllInboxNotificationsRead(optimisticId, readAt);
1958
1987
  },
1959
1988
  () => {
1960
- store.removeOptimisticUpdate(optimisticUpdateId);
1989
+ store.optimisticUpdates.remove(optimisticId);
1961
1990
  }
1962
1991
  );
1963
1992
  }, [client]);
@@ -1967,20 +1996,17 @@ function useDeleteInboxNotification_withClient(client) {
1967
1996
  (inboxNotificationId) => {
1968
1997
  const { store } = getLiveblocksExtrasForClient(client);
1969
1998
  const deletedAt = /* @__PURE__ */ new Date();
1970
- const optimisticUpdateId = store.addOptimisticUpdate({
1999
+ const optimisticId = store.optimisticUpdates.add({
1971
2000
  type: "delete-inbox-notification",
1972
2001
  inboxNotificationId,
1973
2002
  deletedAt
1974
2003
  });
1975
2004
  client.deleteInboxNotification(inboxNotificationId).then(
1976
2005
  () => {
1977
- store.deleteInboxNotification(
1978
- inboxNotificationId,
1979
- optimisticUpdateId
1980
- );
2006
+ store.deleteInboxNotification(inboxNotificationId, optimisticId);
1981
2007
  },
1982
2008
  () => {
1983
- store.removeOptimisticUpdate(optimisticUpdateId);
2009
+ store.optimisticUpdates.remove(optimisticId);
1984
2010
  }
1985
2011
  );
1986
2012
  },
@@ -1991,16 +2017,16 @@ function useDeleteAllInboxNotifications_withClient(client) {
1991
2017
  return useCallback2(() => {
1992
2018
  const { store } = getLiveblocksExtrasForClient(client);
1993
2019
  const deletedAt = /* @__PURE__ */ new Date();
1994
- const optimisticUpdateId = store.addOptimisticUpdate({
2020
+ const optimisticId = store.optimisticUpdates.add({
1995
2021
  type: "delete-all-inbox-notifications",
1996
2022
  deletedAt
1997
2023
  });
1998
2024
  client.deleteAllInboxNotifications().then(
1999
2025
  () => {
2000
- store.deleteAllInboxNotifications(optimisticUpdateId);
2026
+ store.deleteAllInboxNotifications(optimisticId);
2001
2027
  },
2002
2028
  () => {
2003
- store.removeOptimisticUpdate(optimisticUpdateId);
2029
+ store.optimisticUpdates.remove(optimisticId);
2004
2030
  }
2005
2031
  );
2006
2032
  }, [client]);
@@ -2594,8 +2620,8 @@ function getRoomExtrasForClient(client) {
2594
2620
  function makeRoomExtrasForClient(client) {
2595
2621
  const store = getUmbrellaStoreForClient(client);
2596
2622
  const commentsErrorEventSource = makeEventSource2();
2597
- function onMutationFailure(innerError, optimisticUpdateId, createPublicError) {
2598
- store.removeOptimisticUpdate(optimisticUpdateId);
2623
+ function onMutationFailure(innerError, optimisticId, createPublicError) {
2624
+ store.optimisticUpdates.remove(optimisticId);
2599
2625
  if (innerError instanceof HttpError2) {
2600
2626
  const error = handleApiError(innerError);
2601
2627
  commentsErrorEventSource.notify(createPublicError(error));
@@ -2851,7 +2877,7 @@ function RoomProviderInner(props) {
2851
2877
  store.deleteThread(message.threadId, null);
2852
2878
  return;
2853
2879
  }
2854
- const { thread, inboxNotification } = info;
2880
+ const { thread, inboxNotification: maybeNotification } = info;
2855
2881
  const existingThread = store.get1_threads().threadsDB.getEvenIfDeleted(message.threadId);
2856
2882
  switch (message.type) {
2857
2883
  case ServerMsgCode.COMMENT_EDITED:
@@ -2861,10 +2887,16 @@ function RoomProviderInner(props) {
2861
2887
  case ServerMsgCode.COMMENT_REACTION_REMOVED:
2862
2888
  case ServerMsgCode.COMMENT_DELETED:
2863
2889
  if (!existingThread) break;
2864
- store.updateThreadAndNotification(thread, inboxNotification);
2890
+ store.updateThreadifications(
2891
+ [thread],
2892
+ maybeNotification ? [maybeNotification] : []
2893
+ );
2865
2894
  break;
2866
2895
  case ServerMsgCode.COMMENT_CREATED:
2867
- store.updateThreadAndNotification(thread, inboxNotification);
2896
+ store.updateThreadifications(
2897
+ [thread],
2898
+ maybeNotification ? [maybeNotification] : []
2899
+ );
2868
2900
  break;
2869
2901
  default:
2870
2902
  break;
@@ -3301,7 +3333,7 @@ function useCreateRoomThread(roomId) {
3301
3333
  resolved: false
3302
3334
  };
3303
3335
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3304
- const optimisticUpdateId = store.addOptimisticUpdate({
3336
+ const optimisticId = store.optimisticUpdates.add({
3305
3337
  type: "create-thread",
3306
3338
  thread: newThread,
3307
3339
  roomId
@@ -3316,11 +3348,11 @@ function useCreateRoomThread(roomId) {
3316
3348
  attachmentIds
3317
3349
  }).then(
3318
3350
  (thread) => {
3319
- store.createThread(optimisticUpdateId, thread);
3351
+ store.createThread(optimisticId, thread);
3320
3352
  },
3321
3353
  (err) => onMutationFailure(
3322
3354
  err,
3323
- optimisticUpdateId,
3355
+ optimisticId,
3324
3356
  (err2) => new CreateThreadError(err2, {
3325
3357
  roomId,
3326
3358
  threadId,
@@ -3348,7 +3380,7 @@ function useDeleteRoomThread(roomId) {
3348
3380
  if (existing?.comments?.[0]?.userId !== userId) {
3349
3381
  throw new Error("Only the thread creator can delete the thread");
3350
3382
  }
3351
- const optimisticUpdateId = store.addOptimisticUpdate({
3383
+ const optimisticId = store.optimisticUpdates.add({
3352
3384
  type: "delete-thread",
3353
3385
  roomId,
3354
3386
  threadId,
@@ -3356,11 +3388,11 @@ function useDeleteRoomThread(roomId) {
3356
3388
  });
3357
3389
  client[kInternal3].httpClient.deleteThread({ roomId, threadId }).then(
3358
3390
  () => {
3359
- store.deleteThread(threadId, optimisticUpdateId);
3391
+ store.deleteThread(threadId, optimisticId);
3360
3392
  },
3361
3393
  (err) => onMutationFailure(
3362
3394
  err,
3363
- optimisticUpdateId,
3395
+ optimisticId,
3364
3396
  (err2) => new DeleteThreadError(err2, { roomId, threadId })
3365
3397
  )
3366
3398
  );
@@ -3382,7 +3414,7 @@ function useEditRoomThreadMetadata(roomId) {
3382
3414
  const metadata = options.metadata;
3383
3415
  const updatedAt = /* @__PURE__ */ new Date();
3384
3416
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3385
- const optimisticUpdateId = store.addOptimisticUpdate({
3417
+ const optimisticId = store.optimisticUpdates.add({
3386
3418
  type: "edit-thread-metadata",
3387
3419
  metadata,
3388
3420
  threadId,
@@ -3391,16 +3423,11 @@ function useEditRoomThreadMetadata(roomId) {
3391
3423
  client[kInternal3].httpClient.editThreadMetadata({ roomId, threadId, metadata }).then(
3392
3424
  (metadata2) => (
3393
3425
  // Replace the optimistic update by the real thing
3394
- store.patchThread(
3395
- threadId,
3396
- optimisticUpdateId,
3397
- { metadata: metadata2 },
3398
- updatedAt
3399
- )
3426
+ store.patchThread(threadId, optimisticId, { metadata: metadata2 }, updatedAt)
3400
3427
  ),
3401
3428
  (err) => onMutationFailure(
3402
3429
  err,
3403
- optimisticUpdateId,
3430
+ optimisticId,
3404
3431
  (error) => new EditThreadMetadataError(error, {
3405
3432
  roomId,
3406
3433
  threadId,
@@ -3433,18 +3460,18 @@ function useCreateRoomComment(roomId) {
3433
3460
  attachments: attachments ?? []
3434
3461
  };
3435
3462
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3436
- const optimisticUpdateId = store.addOptimisticUpdate({
3463
+ const optimisticId = store.optimisticUpdates.add({
3437
3464
  type: "create-comment",
3438
3465
  comment
3439
3466
  });
3440
3467
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3441
3468
  client[kInternal3].httpClient.createComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3442
3469
  (newComment) => {
3443
- store.createComment(newComment, optimisticUpdateId);
3470
+ store.createComment(newComment, optimisticId);
3444
3471
  },
3445
3472
  (err) => onMutationFailure(
3446
3473
  err,
3447
- optimisticUpdateId,
3474
+ optimisticId,
3448
3475
  (err2) => new CreateCommentError(err2, {
3449
3476
  roomId,
3450
3477
  threadId,
@@ -3483,7 +3510,7 @@ function useEditRoomComment(roomId) {
3483
3510
  );
3484
3511
  return;
3485
3512
  }
3486
- const optimisticUpdateId = store.addOptimisticUpdate({
3513
+ const optimisticId = store.optimisticUpdates.add({
3487
3514
  type: "edit-comment",
3488
3515
  comment: {
3489
3516
  ...comment,
@@ -3495,11 +3522,11 @@ function useEditRoomComment(roomId) {
3495
3522
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3496
3523
  client[kInternal3].httpClient.editComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3497
3524
  (editedComment) => {
3498
- store.editComment(threadId, optimisticUpdateId, editedComment);
3525
+ store.editComment(threadId, optimisticId, editedComment);
3499
3526
  },
3500
3527
  (err) => onMutationFailure(
3501
3528
  err,
3502
- optimisticUpdateId,
3529
+ optimisticId,
3503
3530
  (error) => new EditCommentError(error, {
3504
3531
  roomId,
3505
3532
  threadId,
@@ -3521,7 +3548,7 @@ function useDeleteRoomComment(roomId) {
3521
3548
  ({ threadId, commentId }) => {
3522
3549
  const deletedAt = /* @__PURE__ */ new Date();
3523
3550
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3524
- const optimisticUpdateId = store.addOptimisticUpdate({
3551
+ const optimisticId = store.optimisticUpdates.add({
3525
3552
  type: "delete-comment",
3526
3553
  threadId,
3527
3554
  commentId,
@@ -3530,16 +3557,11 @@ function useDeleteRoomComment(roomId) {
3530
3557
  });
3531
3558
  client[kInternal3].httpClient.deleteComment({ roomId, threadId, commentId }).then(
3532
3559
  () => {
3533
- store.deleteComment(
3534
- threadId,
3535
- optimisticUpdateId,
3536
- commentId,
3537
- deletedAt
3538
- );
3560
+ store.deleteComment(threadId, optimisticId, commentId, deletedAt);
3539
3561
  },
3540
3562
  (err) => onMutationFailure(
3541
3563
  err,
3542
- optimisticUpdateId,
3564
+ optimisticId,
3543
3565
  (error) => new DeleteCommentError(error, {
3544
3566
  roomId,
3545
3567
  threadId,
@@ -3561,7 +3583,7 @@ function useAddRoomCommentReaction(roomId) {
3561
3583
  const createdAt = /* @__PURE__ */ new Date();
3562
3584
  const userId = getCurrentUserId(client);
3563
3585
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3564
- const optimisticUpdateId = store.addOptimisticUpdate({
3586
+ const optimisticId = store.optimisticUpdates.add({
3565
3587
  type: "add-reaction",
3566
3588
  threadId,
3567
3589
  commentId,
@@ -3575,7 +3597,7 @@ function useAddRoomCommentReaction(roomId) {
3575
3597
  (addedReaction) => {
3576
3598
  store.addReaction(
3577
3599
  threadId,
3578
- optimisticUpdateId,
3600
+ optimisticId,
3579
3601
  commentId,
3580
3602
  addedReaction,
3581
3603
  createdAt
@@ -3583,7 +3605,7 @@ function useAddRoomCommentReaction(roomId) {
3583
3605
  },
3584
3606
  (err) => onMutationFailure(
3585
3607
  err,
3586
- optimisticUpdateId,
3608
+ optimisticId,
3587
3609
  (error) => new AddReactionError(error, {
3588
3610
  roomId,
3589
3611
  threadId,
@@ -3606,7 +3628,7 @@ function useRemoveRoomCommentReaction(roomId) {
3606
3628
  const userId = getCurrentUserId(client);
3607
3629
  const removedAt = /* @__PURE__ */ new Date();
3608
3630
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3609
- const optimisticUpdateId = store.addOptimisticUpdate({
3631
+ const optimisticId = store.optimisticUpdates.add({
3610
3632
  type: "remove-reaction",
3611
3633
  threadId,
3612
3634
  commentId,
@@ -3618,7 +3640,7 @@ function useRemoveRoomCommentReaction(roomId) {
3618
3640
  () => {
3619
3641
  store.removeReaction(
3620
3642
  threadId,
3621
- optimisticUpdateId,
3643
+ optimisticId,
3622
3644
  commentId,
3623
3645
  emoji,
3624
3646
  userId,
@@ -3627,7 +3649,7 @@ function useRemoveRoomCommentReaction(roomId) {
3627
3649
  },
3628
3650
  (err) => onMutationFailure(
3629
3651
  err,
3630
- optimisticUpdateId,
3652
+ optimisticId,
3631
3653
  (error) => new RemoveReactionError(error, {
3632
3654
  roomId,
3633
3655
  threadId,
@@ -3655,7 +3677,7 @@ function useMarkRoomThreadAsRead(roomId) {
3655
3677
  );
3656
3678
  if (!inboxNotification) return;
3657
3679
  const now = /* @__PURE__ */ new Date();
3658
- const optimisticUpdateId = store.addOptimisticUpdate({
3680
+ const optimisticId = store.optimisticUpdates.add({
3659
3681
  type: "mark-inbox-notification-as-read",
3660
3682
  inboxNotificationId: inboxNotification.id,
3661
3683
  readAt: now
@@ -3665,16 +3687,16 @@ function useMarkRoomThreadAsRead(roomId) {
3665
3687
  inboxNotificationId: inboxNotification.id
3666
3688
  }).then(
3667
3689
  () => {
3668
- store.updateInboxNotification(
3690
+ store.markInboxNotificationRead(
3669
3691
  inboxNotification.id,
3670
- optimisticUpdateId,
3671
- (inboxNotification2) => ({ ...inboxNotification2, readAt: now })
3692
+ now,
3693
+ optimisticId
3672
3694
  );
3673
3695
  },
3674
3696
  (err) => {
3675
3697
  onMutationFailure(
3676
3698
  err,
3677
- optimisticUpdateId,
3699
+ optimisticId,
3678
3700
  (error) => new MarkInboxNotificationAsReadError(error, {
3679
3701
  inboxNotificationId: inboxNotification.id
3680
3702
  })
@@ -3695,7 +3717,7 @@ function useMarkRoomThreadAsResolved(roomId) {
3695
3717
  (threadId) => {
3696
3718
  const updatedAt = /* @__PURE__ */ new Date();
3697
3719
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3698
- const optimisticUpdateId = store.addOptimisticUpdate({
3720
+ const optimisticId = store.optimisticUpdates.add({
3699
3721
  type: "mark-thread-as-resolved",
3700
3722
  threadId,
3701
3723
  updatedAt
@@ -3704,14 +3726,14 @@ function useMarkRoomThreadAsResolved(roomId) {
3704
3726
  () => {
3705
3727
  store.patchThread(
3706
3728
  threadId,
3707
- optimisticUpdateId,
3729
+ optimisticId,
3708
3730
  { resolved: true },
3709
3731
  updatedAt
3710
3732
  );
3711
3733
  },
3712
3734
  (err) => onMutationFailure(
3713
3735
  err,
3714
- optimisticUpdateId,
3736
+ optimisticId,
3715
3737
  (error) => new MarkThreadAsResolvedError(error, {
3716
3738
  roomId,
3717
3739
  threadId
@@ -3731,7 +3753,7 @@ function useMarkRoomThreadAsUnresolved(roomId) {
3731
3753
  (threadId) => {
3732
3754
  const updatedAt = /* @__PURE__ */ new Date();
3733
3755
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3734
- const optimisticUpdateId = store.addOptimisticUpdate({
3756
+ const optimisticId = store.optimisticUpdates.add({
3735
3757
  type: "mark-thread-as-unresolved",
3736
3758
  threadId,
3737
3759
  updatedAt
@@ -3740,14 +3762,14 @@ function useMarkRoomThreadAsUnresolved(roomId) {
3740
3762
  () => {
3741
3763
  store.patchThread(
3742
3764
  threadId,
3743
- optimisticUpdateId,
3765
+ optimisticId,
3744
3766
  { resolved: false },
3745
3767
  updatedAt
3746
3768
  );
3747
3769
  },
3748
3770
  (err) => onMutationFailure(
3749
3771
  err,
3750
- optimisticUpdateId,
3772
+ optimisticId,
3751
3773
  (error) => new MarkThreadAsUnresolvedError(error, {
3752
3774
  roomId,
3753
3775
  threadId
@@ -3914,22 +3936,18 @@ function useUpdateRoomNotificationSettings() {
3914
3936
  return useCallback3(
3915
3937
  (settings) => {
3916
3938
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3917
- const optimisticUpdateId = store.addOptimisticUpdate({
3939
+ const optimisticId = store.optimisticUpdates.add({
3918
3940
  type: "update-notification-settings",
3919
3941
  roomId: room.id,
3920
3942
  settings
3921
3943
  });
3922
3944
  room.updateNotificationSettings(settings).then(
3923
3945
  (settings2) => {
3924
- store.updateRoomNotificationSettings_confirmOptimisticUpdate(
3925
- room.id,
3926
- optimisticUpdateId,
3927
- settings2
3928
- );
3946
+ store.updateRoomNotificationSettings(room.id, optimisticId, settings2);
3929
3947
  },
3930
3948
  (err) => onMutationFailure(
3931
3949
  err,
3932
- optimisticUpdateId,
3950
+ optimisticId,
3933
3951
  (error) => new UpdateNotificationSettingsError(error, {
3934
3952
  roomId: room.id
3935
3953
  })
@@ -4072,7 +4090,7 @@ function useRoomPermissions(roomId) {
4072
4090
  const client = useClient();
4073
4091
  const store = getRoomExtrasForClient(client).store;
4074
4092
  return useSignal(
4075
- store.permissionHintsByRoomId,
4093
+ store.permissionHints.signal,
4076
4094
  (hints) => hints[roomId] ?? /* @__PURE__ */ new Set()
4077
4095
  );
4078
4096
  }
@@ -4223,4 +4241,4 @@ export {
4223
4241
  _useStorageRoot,
4224
4242
  _useUpdateMyPresence
4225
4243
  };
4226
- //# sourceMappingURL=chunk-UJLD6FYC.mjs.map
4244
+ //# sourceMappingURL=chunk-NZZCQLBR.mjs.map