@liveblocks/react 2.7.0 → 2.7.1

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.
@@ -1,6 +1,6 @@
1
1
  // src/version.ts
2
2
  var PKG_NAME = "@liveblocks/react";
3
- var PKG_VERSION = "2.7.0";
3
+ var PKG_VERSION = "2.7.1";
4
4
  var PKG_FORMAT = "esm";
5
5
 
6
6
  // src/ClientSideSuspense.tsx
@@ -13,123 +13,37 @@ function ClientSideSuspense(props) {
13
13
  return /* @__PURE__ */ React.createElement(React.Suspense, { fallback: props.fallback }, mounted ? typeof props.children === "function" ? props.children() : props.children : props.fallback);
14
14
  }
15
15
 
16
- // src/comments/errors.ts
17
- var CreateThreadError = class extends Error {
18
- constructor(cause, context) {
19
- super("Create thread failed.");
20
- this.cause = cause;
21
- this.context = context;
22
- this.name = "CreateThreadError";
23
- }
24
- };
25
- var DeleteThreadError = class extends Error {
26
- constructor(cause, context) {
27
- super("Delete thread failed.");
28
- this.cause = cause;
29
- this.context = context;
30
- this.name = "DeleteThreadError";
31
- }
32
- };
33
- var EditThreadMetadataError = class extends Error {
34
- constructor(cause, context) {
35
- super("Edit thread metadata failed.");
36
- this.cause = cause;
37
- this.context = context;
38
- this.name = "EditThreadMetadataError";
39
- }
40
- };
41
- var MarkThreadAsResolvedError = class extends Error {
42
- constructor(cause, context) {
43
- super("Mark thread as resolved failed.");
44
- this.cause = cause;
45
- this.context = context;
46
- this.name = "MarkThreadAsResolvedError";
47
- }
48
- };
49
- var MarkThreadAsUnresolvedError = class extends Error {
50
- constructor(cause, context) {
51
- super("Mark thread as unresolved failed.");
52
- this.cause = cause;
53
- this.context = context;
54
- this.name = "MarkThreadAsUnresolvedError";
55
- }
56
- };
57
- var CreateCommentError = class extends Error {
58
- constructor(cause, context) {
59
- super("Create comment failed.");
60
- this.cause = cause;
61
- this.context = context;
62
- this.name = "CreateCommentError";
63
- }
64
- };
65
- var EditCommentError = class extends Error {
66
- constructor(cause, context) {
67
- super("Edit comment failed.");
68
- this.cause = cause;
69
- this.context = context;
70
- this.name = "EditCommentError";
71
- }
72
- };
73
- var DeleteCommentError = class extends Error {
74
- constructor(cause, context) {
75
- super("Delete comment failed.");
76
- this.cause = cause;
77
- this.context = context;
78
- this.name = "DeleteCommentError";
79
- }
80
- };
81
- var AddReactionError = class extends Error {
82
- constructor(cause, context) {
83
- super("Add reaction failed.");
84
- this.cause = cause;
85
- this.context = context;
86
- this.name = "AddReactionError";
87
- }
88
- };
89
- var RemoveReactionError = class extends Error {
90
- constructor(cause, context) {
91
- super("Remove reaction failed.");
92
- this.cause = cause;
93
- this.context = context;
94
- this.name = "RemoveReactionError";
95
- }
96
- };
97
- var MarkInboxNotificationAsReadError = class extends Error {
98
- constructor(cause, context) {
99
- super("Mark inbox notification as read failed.");
100
- this.cause = cause;
101
- this.context = context;
102
- this.name = "MarkInboxNotificationAsReadError";
103
- }
104
- };
105
- var UpdateNotificationSettingsError = class extends Error {
106
- constructor(cause, context) {
107
- super("Update notification settings failed.");
108
- this.cause = cause;
109
- this.context = context;
110
- this.name = "UpdateNotificationSettingsError";
111
- }
112
- };
16
+ // src/contexts.ts
17
+ import * as React2 from "react";
18
+ var RoomContext = React2.createContext(null);
19
+ function useRoomOrNull() {
20
+ return React2.useContext(RoomContext);
21
+ }
22
+ function useIsInsideRoom() {
23
+ const room = useRoomOrNull();
24
+ return room !== null;
25
+ }
113
26
 
114
- // src/room.tsx
115
- import { shallow as shallow2 } from "@liveblocks/client";
27
+ // src/liveblocks.tsx
116
28
  import {
117
- CommentsApiError,
118
- console as console3,
119
- createCommentId,
120
- createThreadId,
121
- deprecateIf,
122
- errorIf,
123
- kInternal as kInternal2,
124
- makeEventSource,
125
- makePoller as makePoller2,
126
- nn,
127
- NotificationsApiError,
128
- ServerMsgCode,
129
- stringify as stringify2
29
+ assert,
30
+ createClient,
31
+ kInternal,
32
+ makePoller,
33
+ memoizeOnSuccess,
34
+ raise,
35
+ shallow as shallow3,
36
+ stringify
130
37
  } from "@liveblocks/core";
131
- import * as React4 from "react";
132
- import { useSyncExternalStoreWithSelector as useSyncExternalStoreWithSelector2 } from "use-sync-external-store/shim/with-selector.js";
38
+ import React3, {
39
+ createContext as createContext2,
40
+ useCallback as useCallback2,
41
+ useContext as useContext2,
42
+ useEffect as useEffect3,
43
+ useMemo
44
+ } from "react";
45
+ import { useSyncExternalStore } from "use-sync-external-store/shim/index.js";
46
+ import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector.js";
133
47
 
134
48
  // src/lib/compare.ts
135
49
  function byFirstCreated(a, b) {
@@ -204,6 +118,21 @@ async function autoRetry(promiseFn, maxTries, backoff) {
204
118
  }
205
119
  }
206
120
 
121
+ // src/lib/shallow2.ts
122
+ import { isPlainObject as isPlainObject2, shallow } from "@liveblocks/core";
123
+ function shallow2(a, b) {
124
+ if (!isPlainObject2(a) || !isPlainObject2(b)) {
125
+ return shallow(a, b);
126
+ }
127
+ const keysA = Object.keys(a);
128
+ if (keysA.length !== Object.keys(b).length) {
129
+ return false;
130
+ }
131
+ return keysA.every(
132
+ (key) => Object.prototype.hasOwnProperty.call(b, key) && shallow(a[key], b[key])
133
+ );
134
+ }
135
+
207
136
  // src/lib/use-initial.ts
208
137
  import { useCallback, useReducer } from "react";
209
138
 
@@ -261,66 +190,102 @@ var use = (
261
190
  }
262
191
  );
263
192
 
264
- // src/liveblocks.tsx
193
+ // src/umbrella-store.ts
265
194
  import {
266
- assert,
267
- createClient,
268
- kInternal,
269
- makePoller,
270
- memoizeOnSuccess,
271
- raise,
272
- shallow,
273
- stringify
195
+ compactObject,
196
+ console as console2,
197
+ createStore,
198
+ mapValues,
199
+ nanoid
274
200
  } from "@liveblocks/core";
275
- import React2, {
276
- createContext,
277
- useCallback as useCallback2,
278
- useContext,
279
- useEffect as useEffect3,
280
- useMemo
281
- } from "react";
282
- import { useSyncExternalStore } from "use-sync-external-store/shim/index.js";
283
- import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector.js";
284
-
285
- // src/umbrella-store.ts
286
- import { console as console2, createStore, mapValues, nanoid } from "@liveblocks/core";
287
201
  var UmbrellaStore = class {
288
202
  constructor() {
203
+ this._prevState = null;
204
+ this._stateCached = null;
289
205
  this._store = createStore({
290
- threads: {},
206
+ rawThreadsById: {},
291
207
  queries: {},
292
208
  optimisticUpdates: [],
293
- inboxNotifications: {},
294
- notificationSettings: {},
295
- versions: {}
209
+ inboxNotificationsById: {},
210
+ notificationSettingsByRoomId: {},
211
+ versionsByRoomId: {}
296
212
  });
297
- this.get = this.get.bind(this);
298
- this.subscribe = this.subscribe.bind(this);
213
+ this.getThreads = this.getThreads.bind(this);
214
+ this.getInboxNotifications = this.getInboxNotifications.bind(this);
215
+ this.getNotificationSettings = this.getNotificationSettings.bind(this);
216
+ this.getVersions = this.getVersions.bind(this);
217
+ this.subscribeThreads = this.subscribeThreads.bind(this);
218
+ this.subscribeInboxNotifications = this.subscribeInboxNotifications.bind(this);
219
+ this.subscribeNotificationSettings = this.subscribeNotificationSettings.bind(this);
220
+ this.subscribeVersions = this.subscribeVersions.bind(this);
221
+ this._hasOptimisticUpdates = this._hasOptimisticUpdates.bind(this);
222
+ this._subscribeOptimisticUpdates = this._subscribeOptimisticUpdates.bind(this);
299
223
  }
300
224
  get() {
301
- return this._store.get();
225
+ const rawState = this._store.get();
226
+ if (this._prevState !== rawState || this._stateCached === null) {
227
+ this._prevState = rawState;
228
+ this._stateCached = applyOptimisticUpdates(rawState);
229
+ }
230
+ return this._stateCached;
231
+ }
232
+ getThreads() {
233
+ return this.get();
234
+ }
235
+ getInboxNotifications() {
236
+ return this.get();
237
+ }
238
+ getNotificationSettings() {
239
+ return this.get();
240
+ }
241
+ getVersions() {
242
+ return this.get();
243
+ }
244
+ /**
245
+ * @private Only used by the E2E test suite.
246
+ */
247
+ _hasOptimisticUpdates() {
248
+ return this._store.get().optimisticUpdates.length > 0;
302
249
  }
303
250
  subscribe(callback) {
304
251
  return this._store.subscribe(callback);
305
252
  }
253
+ /**
254
+ * @private Only used by the E2E test suite.
255
+ */
256
+ _subscribeOptimisticUpdates(callback) {
257
+ return this.subscribe(callback);
258
+ }
259
+ subscribeThreads(callback) {
260
+ return this.subscribe(callback);
261
+ }
262
+ subscribeInboxNotifications(callback) {
263
+ return this.subscribe(callback);
264
+ }
265
+ subscribeNotificationSettings(callback) {
266
+ return this.subscribe(callback);
267
+ }
268
+ subscribeVersions(callback) {
269
+ return this.subscribe(callback);
270
+ }
306
271
  // Direct low-level cache mutations ------------------------------------------------- {{{
307
272
  updateThreadsCache(mapFn) {
308
273
  this._store.set((state) => {
309
- const threads = mapFn(state.threads);
310
- return threads !== state.threads ? { ...state, threads } : state;
274
+ const threads = mapFn(state.rawThreadsById);
275
+ return threads !== state.rawThreadsById ? { ...state, rawThreadsById: threads } : state;
311
276
  });
312
277
  }
313
278
  updateInboxNotificationsCache(mapFn) {
314
279
  this._store.set((state) => {
315
- const inboxNotifications = mapFn(state.inboxNotifications);
316
- return inboxNotifications !== state.inboxNotifications ? { ...state, inboxNotifications } : state;
280
+ const inboxNotifications = mapFn(state.inboxNotificationsById);
281
+ return inboxNotifications !== state.inboxNotificationsById ? { ...state, inboxNotificationsById: inboxNotifications } : state;
317
282
  });
318
283
  }
319
284
  setNotificationSettings(roomId, settings) {
320
285
  this._store.set((state) => ({
321
286
  ...state,
322
- notificationSettings: {
323
- ...state.notificationSettings,
287
+ notificationSettingsByRoomId: {
288
+ ...state.notificationSettingsByRoomId,
324
289
  [roomId]: settings
325
290
  }
326
291
  }));
@@ -328,8 +293,8 @@ var UmbrellaStore = class {
328
293
  setVersions(roomId, versions) {
329
294
  this._store.set((state) => ({
330
295
  ...state,
331
- versions: {
332
- ...state.versions,
296
+ versionsByRoomId: {
297
+ ...state.versionsByRoomId,
333
298
  [roomId]: versions
334
299
  }
335
300
  }));
@@ -449,6 +414,30 @@ var UmbrellaStore = class {
449
414
  });
450
415
  });
451
416
  }
417
+ patchThread(threadId, optimisticUpdateId, patch, updatedAt) {
418
+ return this.updateThread(
419
+ threadId,
420
+ optimisticUpdateId,
421
+ (thread) => ({ ...thread, ...compactObject(patch) }),
422
+ updatedAt
423
+ );
424
+ }
425
+ addReaction(threadId, optimisticUpdateId, commentId, reaction, createdAt) {
426
+ this.updateThread(
427
+ threadId,
428
+ optimisticUpdateId,
429
+ (thread) => applyAddReaction(thread, commentId, reaction),
430
+ createdAt
431
+ );
432
+ }
433
+ removeReaction(threadId, optimisticUpdateId, commentId, emoji, userId, removedAt) {
434
+ this.updateThread(
435
+ threadId,
436
+ optimisticUpdateId,
437
+ (thread) => applyRemoveReaction(thread, commentId, emoji, userId, removedAt),
438
+ removedAt
439
+ );
440
+ }
452
441
  /**
453
442
  * Soft-deletes an existing thread by setting its `deletedAt` value,
454
443
  * replacing the corresponding optimistic update.
@@ -472,13 +461,13 @@ var UmbrellaStore = class {
472
461
  createComment(newComment, optimisticUpdateId) {
473
462
  this._store.batch(() => {
474
463
  this.removeOptimisticUpdate(optimisticUpdateId);
475
- const existingThread = this._store.get().threads[newComment.threadId];
464
+ const existingThread = this._store.get().rawThreadsById[newComment.threadId];
476
465
  if (!existingThread) {
477
466
  return;
478
467
  }
479
468
  this.updateThreadsCache((cache) => ({
480
469
  ...cache,
481
- [newComment.threadId]: upsertComment(existingThread, newComment)
470
+ [newComment.threadId]: applyUpsertComment(existingThread, newComment)
482
471
  }));
483
472
  this.updateInboxNotificationsCache((cache) => {
484
473
  const existingNotification = Object.values(cache).find(
@@ -498,6 +487,21 @@ var UmbrellaStore = class {
498
487
  });
499
488
  });
500
489
  }
490
+ editComment(threadId, optimisticUpdateId, editedComment) {
491
+ return this.updateThread(
492
+ threadId,
493
+ optimisticUpdateId,
494
+ (thread) => applyUpsertComment(thread, editedComment)
495
+ );
496
+ }
497
+ deleteComment(threadId, optimisticUpdateId, commentId, deletedAt) {
498
+ return this.updateThread(
499
+ threadId,
500
+ optimisticUpdateId,
501
+ (thread) => applyDeleteComment(thread, commentId, deletedAt),
502
+ deletedAt
503
+ );
504
+ }
501
505
  updateThreadAndNotification(thread, inboxNotification) {
502
506
  this._store.batch(() => {
503
507
  this.updateThreadsCache((cache) => {
@@ -580,25 +584,19 @@ var UmbrellaStore = class {
580
584
  }
581
585
  };
582
586
  function applyOptimisticUpdates(state) {
583
- const result = {
584
- threads: {
585
- ...state.threads
586
- },
587
- inboxNotifications: {
588
- ...state.inboxNotifications
589
- },
590
- notificationSettings: {
591
- ...state.notificationSettings
592
- }
587
+ const output = {
588
+ threads: { ...state.rawThreadsById },
589
+ inboxNotifications: { ...state.inboxNotificationsById },
590
+ notificationSettings: { ...state.notificationSettingsByRoomId }
593
591
  };
594
592
  for (const optimisticUpdate of state.optimisticUpdates) {
595
593
  switch (optimisticUpdate.type) {
596
594
  case "create-thread": {
597
- result.threads[optimisticUpdate.thread.id] = optimisticUpdate.thread;
595
+ output.threads[optimisticUpdate.thread.id] = optimisticUpdate.thread;
598
596
  break;
599
597
  }
600
598
  case "edit-thread-metadata": {
601
- const thread = result.threads[optimisticUpdate.threadId];
599
+ const thread = output.threads[optimisticUpdate.threadId];
602
600
  if (thread === void 0) {
603
601
  break;
604
602
  }
@@ -608,7 +606,7 @@ function applyOptimisticUpdates(state) {
608
606
  if (thread.updatedAt !== void 0 && thread.updatedAt > optimisticUpdate.updatedAt) {
609
607
  break;
610
608
  }
611
- result.threads[thread.id] = {
609
+ output.threads[thread.id] = {
612
610
  ...thread,
613
611
  updatedAt: optimisticUpdate.updatedAt,
614
612
  metadata: {
@@ -619,49 +617,49 @@ function applyOptimisticUpdates(state) {
619
617
  break;
620
618
  }
621
619
  case "mark-thread-as-resolved": {
622
- const thread = result.threads[optimisticUpdate.threadId];
620
+ const thread = output.threads[optimisticUpdate.threadId];
623
621
  if (thread === void 0) {
624
622
  break;
625
623
  }
626
624
  if (thread.deletedAt !== void 0) {
627
625
  break;
628
626
  }
629
- result.threads[thread.id] = {
627
+ output.threads[thread.id] = {
630
628
  ...thread,
631
629
  resolved: true
632
630
  };
633
631
  break;
634
632
  }
635
633
  case "mark-thread-as-unresolved": {
636
- const thread = result.threads[optimisticUpdate.threadId];
634
+ const thread = output.threads[optimisticUpdate.threadId];
637
635
  if (thread === void 0) {
638
636
  break;
639
637
  }
640
638
  if (thread.deletedAt !== void 0) {
641
639
  break;
642
640
  }
643
- result.threads[thread.id] = {
641
+ output.threads[thread.id] = {
644
642
  ...thread,
645
643
  resolved: false
646
644
  };
647
645
  break;
648
646
  }
649
647
  case "create-comment": {
650
- const thread = result.threads[optimisticUpdate.comment.threadId];
648
+ const thread = output.threads[optimisticUpdate.comment.threadId];
651
649
  if (thread === void 0) {
652
650
  break;
653
651
  }
654
- result.threads[thread.id] = upsertComment(
652
+ output.threads[thread.id] = applyUpsertComment(
655
653
  thread,
656
654
  optimisticUpdate.comment
657
655
  );
658
- const inboxNotification = Object.values(result.inboxNotifications).find(
656
+ const inboxNotification = Object.values(output.inboxNotifications).find(
659
657
  (notification) => notification.kind === "thread" && notification.threadId === thread.id
660
658
  );
661
659
  if (inboxNotification === void 0) {
662
660
  break;
663
661
  }
664
- result.inboxNotifications[inboxNotification.id] = {
662
+ output.inboxNotifications[inboxNotification.id] = {
665
663
  ...inboxNotification,
666
664
  notifiedAt: optimisticUpdate.comment.createdAt,
667
665
  readAt: optimisticUpdate.comment.createdAt
@@ -669,22 +667,22 @@ function applyOptimisticUpdates(state) {
669
667
  break;
670
668
  }
671
669
  case "edit-comment": {
672
- const thread = result.threads[optimisticUpdate.comment.threadId];
670
+ const thread = output.threads[optimisticUpdate.comment.threadId];
673
671
  if (thread === void 0) {
674
672
  break;
675
673
  }
676
- result.threads[thread.id] = upsertComment(
674
+ output.threads[thread.id] = applyUpsertComment(
677
675
  thread,
678
676
  optimisticUpdate.comment
679
677
  );
680
678
  break;
681
679
  }
682
680
  case "delete-comment": {
683
- const thread = result.threads[optimisticUpdate.threadId];
681
+ const thread = output.threads[optimisticUpdate.threadId];
684
682
  if (thread === void 0) {
685
683
  break;
686
684
  }
687
- result.threads[thread.id] = deleteComment(
685
+ output.threads[thread.id] = applyDeleteComment(
688
686
  thread,
689
687
  optimisticUpdate.commentId,
690
688
  optimisticUpdate.deletedAt
@@ -692,12 +690,12 @@ function applyOptimisticUpdates(state) {
692
690
  break;
693
691
  }
694
692
  case "delete-thread": {
695
- const thread = result.threads[optimisticUpdate.threadId];
693
+ const thread = output.threads[optimisticUpdate.threadId];
696
694
  if (thread === void 0) {
697
695
  break;
698
696
  }
699
- result.threads[optimisticUpdate.threadId] = {
700
- ...result.threads[optimisticUpdate.threadId],
697
+ output.threads[optimisticUpdate.threadId] = {
698
+ ...output.threads[optimisticUpdate.threadId],
701
699
  deletedAt: optimisticUpdate.deletedAt,
702
700
  updatedAt: optimisticUpdate.deletedAt,
703
701
  comments: []
@@ -705,11 +703,11 @@ function applyOptimisticUpdates(state) {
705
703
  break;
706
704
  }
707
705
  case "add-reaction": {
708
- const thread = result.threads[optimisticUpdate.threadId];
706
+ const thread = output.threads[optimisticUpdate.threadId];
709
707
  if (thread === void 0) {
710
708
  break;
711
709
  }
712
- result.threads[thread.id] = addReaction(
710
+ output.threads[thread.id] = applyAddReaction(
713
711
  thread,
714
712
  optimisticUpdate.commentId,
715
713
  optimisticUpdate.reaction
@@ -717,11 +715,11 @@ function applyOptimisticUpdates(state) {
717
715
  break;
718
716
  }
719
717
  case "remove-reaction": {
720
- const thread = result.threads[optimisticUpdate.threadId];
718
+ const thread = output.threads[optimisticUpdate.threadId];
721
719
  if (thread === void 0) {
722
720
  break;
723
721
  }
724
- result.threads[thread.id] = removeReaction(
722
+ output.threads[thread.id] = applyRemoveReaction(
725
723
  thread,
726
724
  optimisticUpdate.commentId,
727
725
  optimisticUpdate.emoji,
@@ -731,16 +729,16 @@ function applyOptimisticUpdates(state) {
731
729
  break;
732
730
  }
733
731
  case "mark-inbox-notification-as-read": {
734
- result.inboxNotifications[optimisticUpdate.inboxNotificationId] = {
735
- ...state.inboxNotifications[optimisticUpdate.inboxNotificationId],
732
+ output.inboxNotifications[optimisticUpdate.inboxNotificationId] = {
733
+ ...state.inboxNotificationsById[optimisticUpdate.inboxNotificationId],
736
734
  readAt: optimisticUpdate.readAt
737
735
  };
738
736
  break;
739
737
  }
740
738
  case "mark-all-inbox-notifications-as-read": {
741
- for (const id in result.inboxNotifications) {
742
- result.inboxNotifications[id] = {
743
- ...result.inboxNotifications[id],
739
+ for (const id in output.inboxNotifications) {
740
+ output.inboxNotifications[id] = {
741
+ ...output.inboxNotifications[id],
744
742
  readAt: optimisticUpdate.readAt
745
743
  };
746
744
  }
@@ -750,23 +748,43 @@ function applyOptimisticUpdates(state) {
750
748
  const {
751
749
  [optimisticUpdate.inboxNotificationId]: _,
752
750
  ...inboxNotifications
753
- } = result.inboxNotifications;
754
- result.inboxNotifications = inboxNotifications;
751
+ } = output.inboxNotifications;
752
+ output.inboxNotifications = inboxNotifications;
755
753
  break;
756
754
  }
757
755
  case "delete-all-inbox-notifications": {
758
- result.inboxNotifications = {};
756
+ output.inboxNotifications = {};
759
757
  break;
760
758
  }
761
759
  case "update-notification-settings": {
762
- result.notificationSettings[optimisticUpdate.roomId] = {
763
- ...result.notificationSettings[optimisticUpdate.roomId],
760
+ output.notificationSettings[optimisticUpdate.roomId] = {
761
+ ...output.notificationSettings[optimisticUpdate.roomId],
764
762
  ...optimisticUpdate.settings
765
763
  };
766
764
  }
767
765
  }
768
766
  }
769
- return result;
767
+ const cleanedThreads = (
768
+ // Don't expose any soft-deleted threads
769
+ Object.values(output.threads).filter(
770
+ (thread) => !thread.deletedAt
771
+ )
772
+ );
773
+ const cleanedNotifications = (
774
+ // Sort so that the most recent notifications are first
775
+ Object.values(output.inboxNotifications).sort(
776
+ (a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime()
777
+ )
778
+ );
779
+ return {
780
+ inboxNotifications: cleanedNotifications,
781
+ inboxNotificationsById: output.inboxNotifications,
782
+ notificationSettingsByRoomId: output.notificationSettings,
783
+ queries: state.queries,
784
+ threads: cleanedThreads,
785
+ threadsById: output.threads,
786
+ versionsByRoomId: state.versionsByRoomId
787
+ };
770
788
  }
771
789
  function applyThreadUpdates(existingThreads, updates) {
772
790
  const updatedThreads = { ...existingThreads };
@@ -819,7 +837,7 @@ function compareInboxNotifications(inboxNotificationA, inboxNotificationB) {
819
837
  }
820
838
  return 0;
821
839
  }
822
- function upsertComment(thread, comment) {
840
+ function applyUpsertComment(thread, comment) {
823
841
  if (thread.deletedAt !== void 0) {
824
842
  return thread;
825
843
  }
@@ -864,7 +882,7 @@ function upsertComment(thread, comment) {
864
882
  }
865
883
  return thread;
866
884
  }
867
- function deleteComment(thread, commentId, deletedAt) {
885
+ function applyDeleteComment(thread, commentId, deletedAt) {
868
886
  if (thread.deletedAt !== void 0) {
869
887
  return thread;
870
888
  }
@@ -898,7 +916,7 @@ function deleteComment(thread, commentId, deletedAt) {
898
916
  comments: updatedComments
899
917
  };
900
918
  }
901
- function addReaction(thread, commentId, reaction) {
919
+ function applyAddReaction(thread, commentId, reaction) {
902
920
  if (thread.deletedAt !== void 0) {
903
921
  return thread;
904
922
  }
@@ -925,7 +943,7 @@ function addReaction(thread, commentId, reaction) {
925
943
  comments: updatedComments
926
944
  };
927
945
  }
928
- function removeReaction(thread, commentId, emoji, userId, removedAt) {
946
+ function applyRemoveReaction(thread, commentId, emoji, userId, removedAt) {
929
947
  if (thread.deletedAt !== void 0) {
930
948
  return thread;
931
949
  }
@@ -984,7 +1002,7 @@ function upsertReaction(reactions, reaction) {
984
1002
  }
985
1003
 
986
1004
  // src/liveblocks.tsx
987
- var ClientContext = createContext(null);
1005
+ var ClientContext = createContext2(null);
988
1006
  function missingUserError(userId) {
989
1007
  return new Error(`resolveUsers didn't return anything for user '${userId}'`);
990
1008
  }
@@ -1013,24 +1031,13 @@ function selectorFor_useInboxNotifications(state) {
1013
1031
  };
1014
1032
  }
1015
1033
  return {
1016
- inboxNotifications: selectInboxNotifications(state),
1034
+ inboxNotifications: state.inboxNotifications,
1017
1035
  isLoading: false
1018
1036
  };
1019
1037
  }
1020
- function selectUserThreads(state, options) {
1021
- const result = applyOptimisticUpdates(state);
1022
- let threads = Object.values(result.threads).filter(
1023
- (thread) => !thread.deletedAt
1024
- );
1025
- const query = options.query;
1026
- if (query) {
1027
- threads = threads.filter(makeThreadsFilter(query));
1028
- }
1029
- return threads.sort(byMostRecentlyUpdated);
1030
- }
1031
1038
  function selectUnreadInboxNotificationsCount(state) {
1032
1039
  let count = 0;
1033
- for (const notification of selectInboxNotifications(state)) {
1040
+ for (const notification of state.inboxNotifications) {
1034
1041
  if (notification.readAt === null || notification.readAt < notification.notifiedAt) {
1035
1042
  count++;
1036
1043
  }
@@ -1091,11 +1098,17 @@ function selectorFor_useRoomInfo(state, roomId) {
1091
1098
  info: state.data
1092
1099
  };
1093
1100
  }
1094
- function selectInboxNotifications(state) {
1095
- const result = applyOptimisticUpdates(state);
1096
- return Object.values(result.inboxNotifications).sort(
1097
- // Sort so that the most recent notifications are first
1098
- (a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime()
1101
+ function selectThreads(state, options) {
1102
+ let threads = state.threads;
1103
+ if (options.roomId !== null) {
1104
+ threads = threads.filter((thread) => thread.roomId === options.roomId);
1105
+ }
1106
+ const query = options.query;
1107
+ if (query) {
1108
+ threads = threads.filter(makeThreadsFilter(query));
1109
+ }
1110
+ return threads.sort(
1111
+ options.orderBy === "last-update" ? byMostRecentlyUpdated : byFirstCreated
1099
1112
  );
1100
1113
  }
1101
1114
  function getOrCreateContextBundle(client) {
@@ -1294,7 +1307,7 @@ function makeLiveblocksContextBundle(client) {
1294
1307
  const useDeleteAllInboxNotifications2 = () => useDeleteAllInboxNotifications_withClient(client);
1295
1308
  function LiveblocksProvider2(props) {
1296
1309
  useEnsureNoLiveblocksProvider();
1297
- return /* @__PURE__ */ React2.createElement(ClientContext.Provider, { value: client }, props.children);
1310
+ return /* @__PURE__ */ React3.createElement(ClientContext.Provider, { value: client }, props.children);
1298
1311
  }
1299
1312
  const shared = createSharedContext(client);
1300
1313
  const bundle = {
@@ -1330,11 +1343,11 @@ function useInboxNotifications_withClient(client) {
1330
1343
  }, [loadInboxNotifications]);
1331
1344
  useEnableInboxNotificationsPolling();
1332
1345
  return useSyncExternalStoreWithSelector(
1333
- store.subscribe,
1334
- store.get,
1335
- store.get,
1346
+ store.subscribeInboxNotifications,
1347
+ store.getInboxNotifications,
1348
+ store.getInboxNotifications,
1336
1349
  selectorFor_useInboxNotifications,
1337
- shallow
1350
+ shallow3
1338
1351
  );
1339
1352
  }
1340
1353
  function useInboxNotificationsSuspense_withClient(client) {
@@ -1352,11 +1365,11 @@ function useUnreadInboxNotificationsCount_withClient(client) {
1352
1365
  }, [loadInboxNotifications]);
1353
1366
  useEnableInboxNotificationsPolling();
1354
1367
  return useSyncExternalStoreWithSelector(
1355
- store.subscribe,
1356
- store.get,
1357
- store.get,
1368
+ store.subscribeInboxNotifications,
1369
+ store.getInboxNotifications,
1370
+ store.getInboxNotifications,
1358
1371
  selectorFor_useUnreadInboxNotificationsCount,
1359
- shallow
1372
+ shallow3
1360
1373
  );
1361
1374
  }
1362
1375
  function useUnreadInboxNotificationsCountSuspense_withClient(client) {
@@ -1461,13 +1474,13 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
1461
1474
  const { store } = getExtrasForClient(client);
1462
1475
  const selector = useCallback2(
1463
1476
  (state) => {
1464
- const inboxNotification = state.inboxNotifications[inboxNotificationId] ?? raise(`Inbox notification with ID "${inboxNotificationId}" not found`);
1477
+ const inboxNotification = state.inboxNotificationsById[inboxNotificationId] ?? raise(`Inbox notification with ID "${inboxNotificationId}" not found`);
1465
1478
  if (inboxNotification.kind !== "thread") {
1466
1479
  raise(
1467
1480
  `Inbox notification with ID "${inboxNotificationId}" is not of kind "thread"`
1468
1481
  );
1469
1482
  }
1470
- const thread = state.threads[inboxNotification.threadId] ?? raise(
1483
+ const thread = state.threadsById[inboxNotification.threadId] ?? raise(
1471
1484
  `Thread with ID "${inboxNotification.threadId}" not found, this inbox notification might not be of kind "thread"`
1472
1485
  );
1473
1486
  return thread;
@@ -1475,9 +1488,9 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
1475
1488
  [inboxNotificationId]
1476
1489
  );
1477
1490
  return useSyncExternalStoreWithSelector(
1478
- store.subscribe,
1479
- store.get,
1480
- store.get,
1491
+ store.subscribeInboxNotifications,
1492
+ store.getInboxNotifications,
1493
+ store.getInboxNotifications,
1481
1494
  selector
1482
1495
  );
1483
1496
  }
@@ -1499,7 +1512,7 @@ function useUser_withClient(client, userId) {
1499
1512
  getUserState,
1500
1513
  getUserState,
1501
1514
  selector,
1502
- shallow
1515
+ shallow3
1503
1516
  );
1504
1517
  }
1505
1518
  function useUserSuspense_withClient(client, userId) {
@@ -1550,7 +1563,7 @@ function useRoomInfo_withClient(client, roomId) {
1550
1563
  getRoomInfoState,
1551
1564
  getRoomInfoState,
1552
1565
  selector,
1553
- shallow
1566
+ shallow3
1554
1567
  );
1555
1568
  }
1556
1569
  function useRoomInfoSuspense_withClient(client, roomId) {
@@ -1591,13 +1604,13 @@ function createSharedContext(client) {
1591
1604
  useClient: useClient2,
1592
1605
  useUser: (userId) => useUser_withClient(client, userId),
1593
1606
  useRoomInfo: (roomId) => useRoomInfo_withClient(client, roomId),
1594
- useIsInsideRoom: _useIsInsideRoom
1607
+ useIsInsideRoom
1595
1608
  },
1596
1609
  suspense: {
1597
1610
  useClient: useClient2,
1598
1611
  useUser: (userId) => useUserSuspense_withClient(client, userId),
1599
1612
  useRoomInfo: (roomId) => useRoomInfoSuspense_withClient(client, roomId),
1600
- useIsInsideRoom: _useIsInsideRoom
1613
+ useIsInsideRoom
1601
1614
  }
1602
1615
  };
1603
1616
  }
@@ -1610,14 +1623,14 @@ function useEnsureNoLiveblocksProvider(options) {
1610
1623
  }
1611
1624
  }
1612
1625
  function useClientOrNull() {
1613
- return useContext(ClientContext);
1626
+ return useContext2(ClientContext);
1614
1627
  }
1615
1628
  function useClient() {
1616
1629
  return useClientOrNull() ?? raise("LiveblocksProvider is missing from the React tree.");
1617
1630
  }
1618
1631
  function LiveblocksProviderWithClient(props) {
1619
1632
  useEnsureNoLiveblocksProvider(props);
1620
- return /* @__PURE__ */ React2.createElement(ClientContext.Provider, { value: props.client }, props.children);
1633
+ return /* @__PURE__ */ React3.createElement(ClientContext.Provider, { value: props.client }, props.children);
1621
1634
  }
1622
1635
  function LiveblocksProvider(props) {
1623
1636
  const { children, ...o } = props;
@@ -1645,7 +1658,7 @@ function LiveblocksProvider(props) {
1645
1658
  )
1646
1659
  };
1647
1660
  const client = useMemo(() => createClient(options), []);
1648
- return /* @__PURE__ */ React2.createElement(LiveblocksProviderWithClient, { client }, children);
1661
+ return /* @__PURE__ */ React3.createElement(LiveblocksProviderWithClient, { client }, children);
1649
1662
  }
1650
1663
  function createLiveblocksContext(client) {
1651
1664
  return getOrCreateContextBundle(client);
@@ -1655,7 +1668,7 @@ function useUserThreads_experimental(options = {
1655
1668
  metadata: {}
1656
1669
  }
1657
1670
  }) {
1658
- const queryKey = React2.useMemo(
1671
+ const queryKey = React3.useMemo(
1659
1672
  () => makeUserThreadsQueryKey(options.query),
1660
1673
  [options]
1661
1674
  );
@@ -1681,18 +1694,24 @@ function useUserThreads_experimental(options = {
1681
1694
  };
1682
1695
  }
1683
1696
  return {
1684
- threads: selectUserThreads(state, options),
1697
+ threads: selectThreads(state, {
1698
+ roomId: null,
1699
+ // Do _not_ filter by roomId
1700
+ query: options.query,
1701
+ orderBy: "last-update"
1702
+ }),
1685
1703
  isLoading: false
1686
1704
  };
1687
1705
  },
1688
1706
  [queryKey, options]
1689
1707
  );
1690
1708
  return useSyncExternalStoreWithSelector(
1691
- store.subscribe,
1692
- store.get,
1693
- store.get,
1709
+ store.subscribeThreads,
1710
+ store.getThreads,
1711
+ store.getThreads,
1694
1712
  selector,
1695
- shallow
1713
+ shallow2
1714
+ // NOTE: Using 2-level-deep shallow check here, because the result of selectThreads() is not stable!
1696
1715
  );
1697
1716
  }
1698
1717
  function useUserThreadsSuspense_experimental(options = {
@@ -1700,17 +1719,17 @@ function useUserThreadsSuspense_experimental(options = {
1700
1719
  metadata: {}
1701
1720
  }
1702
1721
  }) {
1703
- const queryKey = React2.useMemo(
1722
+ const queryKey = React3.useMemo(
1704
1723
  () => makeUserThreadsQueryKey(options.query),
1705
1724
  [options]
1706
1725
  );
1707
1726
  const client = useClient();
1708
1727
  const { store, getUserThreads } = getExtrasForClient(client);
1709
- React2.useEffect(() => {
1728
+ React3.useEffect(() => {
1710
1729
  const { incrementUserThreadsQuerySubscribers } = getExtrasForClient(client);
1711
1730
  return incrementUserThreadsQuerySubscribers(queryKey);
1712
1731
  }, [client, queryKey]);
1713
- const query = store.get().queries[queryKey];
1732
+ const query = store.getThreads().queries[queryKey];
1714
1733
  if (query === void 0 || query.isLoading) {
1715
1734
  throw getUserThreads(queryKey, options);
1716
1735
  }
@@ -1720,18 +1739,24 @@ function useUserThreadsSuspense_experimental(options = {
1720
1739
  const selector = useCallback2(
1721
1740
  (state) => {
1722
1741
  return {
1723
- threads: selectUserThreads(state, options),
1742
+ threads: selectThreads(state, {
1743
+ roomId: null,
1744
+ // Do _not_ filter by roomId
1745
+ query: options.query,
1746
+ orderBy: "last-update"
1747
+ }),
1724
1748
  isLoading: false
1725
1749
  };
1726
1750
  },
1727
1751
  [options]
1728
1752
  );
1729
1753
  return useSyncExternalStoreWithSelector(
1730
- store.subscribe,
1731
- store.get,
1732
- store.get,
1754
+ store.subscribeThreads,
1755
+ store.getThreads,
1756
+ store.getThreads,
1733
1757
  selector,
1734
- shallow
1758
+ shallow2
1759
+ // NOTE: Using 2-level-deep shallow check here, because the result of selectThreads() is not stable!
1735
1760
  );
1736
1761
  }
1737
1762
  function useInboxNotifications() {
@@ -1785,8 +1810,126 @@ var _useUserThreads_experimental = useUserThreads_experimental;
1785
1810
  var _useUserThreadsSuspense_experimental = useUserThreadsSuspense_experimental;
1786
1811
  var makeUserThreadsQueryKey = (options) => `${USER_THREADS_QUERY}:${stringify(options)}`;
1787
1812
 
1813
+ // src/types/errors.ts
1814
+ var CreateThreadError = class extends Error {
1815
+ constructor(cause, context) {
1816
+ super("Create thread failed.");
1817
+ this.cause = cause;
1818
+ this.context = context;
1819
+ this.name = "CreateThreadError";
1820
+ }
1821
+ };
1822
+ var DeleteThreadError = class extends Error {
1823
+ constructor(cause, context) {
1824
+ super("Delete thread failed.");
1825
+ this.cause = cause;
1826
+ this.context = context;
1827
+ this.name = "DeleteThreadError";
1828
+ }
1829
+ };
1830
+ var EditThreadMetadataError = class extends Error {
1831
+ constructor(cause, context) {
1832
+ super("Edit thread metadata failed.");
1833
+ this.cause = cause;
1834
+ this.context = context;
1835
+ this.name = "EditThreadMetadataError";
1836
+ }
1837
+ };
1838
+ var MarkThreadAsResolvedError = class extends Error {
1839
+ constructor(cause, context) {
1840
+ super("Mark thread as resolved failed.");
1841
+ this.cause = cause;
1842
+ this.context = context;
1843
+ this.name = "MarkThreadAsResolvedError";
1844
+ }
1845
+ };
1846
+ var MarkThreadAsUnresolvedError = class extends Error {
1847
+ constructor(cause, context) {
1848
+ super("Mark thread as unresolved failed.");
1849
+ this.cause = cause;
1850
+ this.context = context;
1851
+ this.name = "MarkThreadAsUnresolvedError";
1852
+ }
1853
+ };
1854
+ var CreateCommentError = class extends Error {
1855
+ constructor(cause, context) {
1856
+ super("Create comment failed.");
1857
+ this.cause = cause;
1858
+ this.context = context;
1859
+ this.name = "CreateCommentError";
1860
+ }
1861
+ };
1862
+ var EditCommentError = class extends Error {
1863
+ constructor(cause, context) {
1864
+ super("Edit comment failed.");
1865
+ this.cause = cause;
1866
+ this.context = context;
1867
+ this.name = "EditCommentError";
1868
+ }
1869
+ };
1870
+ var DeleteCommentError = class extends Error {
1871
+ constructor(cause, context) {
1872
+ super("Delete comment failed.");
1873
+ this.cause = cause;
1874
+ this.context = context;
1875
+ this.name = "DeleteCommentError";
1876
+ }
1877
+ };
1878
+ var AddReactionError = class extends Error {
1879
+ constructor(cause, context) {
1880
+ super("Add reaction failed.");
1881
+ this.cause = cause;
1882
+ this.context = context;
1883
+ this.name = "AddReactionError";
1884
+ }
1885
+ };
1886
+ var RemoveReactionError = class extends Error {
1887
+ constructor(cause, context) {
1888
+ super("Remove reaction failed.");
1889
+ this.cause = cause;
1890
+ this.context = context;
1891
+ this.name = "RemoveReactionError";
1892
+ }
1893
+ };
1894
+ var MarkInboxNotificationAsReadError = class extends Error {
1895
+ constructor(cause, context) {
1896
+ super("Mark inbox notification as read failed.");
1897
+ this.cause = cause;
1898
+ this.context = context;
1899
+ this.name = "MarkInboxNotificationAsReadError";
1900
+ }
1901
+ };
1902
+ var UpdateNotificationSettingsError = class extends Error {
1903
+ constructor(cause, context) {
1904
+ super("Update notification settings failed.");
1905
+ this.cause = cause;
1906
+ this.context = context;
1907
+ this.name = "UpdateNotificationSettingsError";
1908
+ }
1909
+ };
1910
+
1911
+ // src/room.tsx
1912
+ import { shallow as shallow4 } from "@liveblocks/client";
1913
+ import {
1914
+ CommentsApiError,
1915
+ console as console3,
1916
+ createCommentId,
1917
+ createThreadId,
1918
+ deprecateIf,
1919
+ errorIf,
1920
+ kInternal as kInternal2,
1921
+ makeEventSource,
1922
+ makePoller as makePoller2,
1923
+ nn,
1924
+ NotificationsApiError,
1925
+ ServerMsgCode,
1926
+ stringify as stringify2
1927
+ } from "@liveblocks/core";
1928
+ import * as React5 from "react";
1929
+ import { useSyncExternalStoreWithSelector as useSyncExternalStoreWithSelector2 } from "use-sync-external-store/shim/with-selector.js";
1930
+
1788
1931
  // src/use-scroll-to-comment-on-load-effect.ts
1789
- import * as React3 from "react";
1932
+ import * as React4 from "react";
1790
1933
  function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
1791
1934
  if (shouldScrollOnLoad === false) return;
1792
1935
  if (state.isLoading) return;
@@ -1805,7 +1948,7 @@ function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
1805
1948
  comment.scrollIntoView();
1806
1949
  }
1807
1950
  function useScrollToCommentOnLoadEffect(shouldScrollOnLoad, state) {
1808
- React3.useEffect(
1951
+ React4.useEffect(
1809
1952
  () => {
1810
1953
  handleScrollToCommentOnLoad(shouldScrollOnLoad, state);
1811
1954
  },
@@ -1848,20 +1991,8 @@ function alwaysNull() {
1848
1991
  function selectorFor_useOthersConnectionIds(others) {
1849
1992
  return others.map((user) => user.connectionId);
1850
1993
  }
1851
- function selectRoomThreads(roomId, state, options) {
1852
- const result = applyOptimisticUpdates(state);
1853
- let threads = Object.values(result.threads).filter(
1854
- (thread) => !thread.deletedAt
1855
- );
1856
- threads = threads.filter((thread) => thread.roomId === roomId);
1857
- const query = options.query;
1858
- if (query) {
1859
- threads = threads.filter(makeThreadsFilter(query));
1860
- }
1861
- return threads.sort(byFirstCreated);
1862
- }
1863
1994
  function selectNotificationSettings(roomId, state) {
1864
- const { notificationSettings } = applyOptimisticUpdates(state);
1995
+ const notificationSettings = state.notificationSettingsByRoomId;
1865
1996
  return nn(notificationSettings[roomId]);
1866
1997
  }
1867
1998
  function makeMutationContext(room) {
@@ -2097,10 +2228,9 @@ function makeExtrasForClient2(client) {
2097
2228
  onMutationFailure
2098
2229
  };
2099
2230
  }
2100
- var RoomContext = React4.createContext(null);
2101
2231
  function makeRoomContextBundle(client) {
2102
2232
  function RoomProvider_withImplicitLiveblocksProvider(props) {
2103
- return /* @__PURE__ */ React4.createElement(LiveblocksProviderWithClient, { client, allowNesting: true }, /* @__PURE__ */ React4.createElement(RoomProvider, { ...props }));
2233
+ return /* @__PURE__ */ React5.createElement(LiveblocksProviderWithClient, { client, allowNesting: true }, /* @__PURE__ */ React5.createElement(RoomProvider, { ...props }));
2104
2234
  }
2105
2235
  const shared = createSharedContext(client);
2106
2236
  const bundle = {
@@ -2202,10 +2332,10 @@ function makeRoomContextBundle(client) {
2202
2332
  }
2203
2333
  function RoomProvider(props) {
2204
2334
  const client = useClient();
2205
- const [cache] = React4.useState(
2335
+ const [cache] = React5.useState(
2206
2336
  () => /* @__PURE__ */ new Map()
2207
2337
  );
2208
- const stableEnterRoom = React4.useCallback(
2338
+ const stableEnterRoom = React5.useCallback(
2209
2339
  (roomId, options) => {
2210
2340
  const cached = cache.get(roomId);
2211
2341
  if (cached) return cached;
@@ -2220,7 +2350,7 @@ function RoomProvider(props) {
2220
2350
  },
2221
2351
  [client, cache]
2222
2352
  );
2223
- return /* @__PURE__ */ React4.createElement(
2353
+ return /* @__PURE__ */ React5.createElement(
2224
2354
  RoomProviderInner,
2225
2355
  {
2226
2356
  ...props,
@@ -2240,7 +2370,7 @@ function RoomProviderInner(props) {
2240
2370
  if (!isString(roomId)) {
2241
2371
  throw new Error("RoomProvider id property should be a string.");
2242
2372
  }
2243
- const majorReactVersion = parseInt(React4.version) || 1;
2373
+ const majorReactVersion = parseInt(React5.version) || 1;
2244
2374
  const oldReactVersion = majorReactVersion < 18;
2245
2375
  errorIf(
2246
2376
  oldReactVersion && props.unstable_batchedUpdates === void 0,
@@ -2257,14 +2387,14 @@ function RoomProviderInner(props) {
2257
2387
  unstable_batchedUpdates: props.unstable_batchedUpdates,
2258
2388
  autoConnect: props.autoConnect ?? typeof window !== "undefined"
2259
2389
  });
2260
- const [{ room }, setRoomLeavePair] = React4.useState(
2390
+ const [{ room }, setRoomLeavePair] = React5.useState(
2261
2391
  () => stableEnterRoom(roomId, {
2262
2392
  ...frozenProps,
2263
2393
  autoConnect: false
2264
2394
  // Deliberately using false here on the first render, see below
2265
2395
  })
2266
2396
  );
2267
- React4.useEffect(() => {
2397
+ React5.useEffect(() => {
2268
2398
  const { store } = getExtrasForClient2(client);
2269
2399
  async function handleCommentEvent(message) {
2270
2400
  if (message.type === ServerMsgCode.THREAD_DELETED) {
@@ -2277,7 +2407,7 @@ function RoomProviderInner(props) {
2277
2407
  return;
2278
2408
  }
2279
2409
  const { thread, inboxNotification } = info;
2280
- const existingThread = store.get().threads[message.threadId];
2410
+ const existingThread = store.getThreads().threadsById[message.threadId];
2281
2411
  switch (message.type) {
2282
2412
  case ServerMsgCode.COMMENT_EDITED:
2283
2413
  case ServerMsgCode.THREAD_METADATA_UPDATED:
@@ -2299,11 +2429,11 @@ function RoomProviderInner(props) {
2299
2429
  (message) => void handleCommentEvent(message)
2300
2430
  );
2301
2431
  }, [client, room]);
2302
- React4.useEffect(() => {
2432
+ React5.useEffect(() => {
2303
2433
  const { getThreadsUpdates } = getExtrasForClient2(client);
2304
2434
  void getThreadsUpdates(room.id);
2305
2435
  }, [client, room.id]);
2306
- React4.useEffect(() => {
2436
+ React5.useEffect(() => {
2307
2437
  function handleIsOnline() {
2308
2438
  const { getThreadsUpdates } = getExtrasForClient2(client);
2309
2439
  void getThreadsUpdates(room.id);
@@ -2313,7 +2443,7 @@ function RoomProviderInner(props) {
2313
2443
  window.removeEventListener("online", handleIsOnline);
2314
2444
  };
2315
2445
  }, [client, room.id]);
2316
- React4.useEffect(() => {
2446
+ React5.useEffect(() => {
2317
2447
  const pair = stableEnterRoom(roomId, frozenProps);
2318
2448
  setRoomLeavePair(pair);
2319
2449
  const { room: room2, leave } = pair;
@@ -2324,7 +2454,7 @@ function RoomProviderInner(props) {
2324
2454
  leave();
2325
2455
  };
2326
2456
  }, [roomId, frozenProps, stableEnterRoom]);
2327
- return /* @__PURE__ */ React4.createElement(RoomContext.Provider, { value: room }, props.children);
2457
+ return /* @__PURE__ */ React5.createElement(RoomContext.Provider, { value: room }, props.children);
2328
2458
  }
2329
2459
  function useRoom() {
2330
2460
  const room = useRoomOrNull();
@@ -2333,10 +2463,6 @@ function useRoom() {
2333
2463
  }
2334
2464
  return room;
2335
2465
  }
2336
- function useIsInsideRoom() {
2337
- const room = useRoomOrNull();
2338
- return room !== null;
2339
- }
2340
2466
  function useStatus() {
2341
2467
  const room = useRoom();
2342
2468
  const subscribe = room.events.status.subscribe;
@@ -2361,9 +2487,9 @@ function useStorageStatusImmediate() {
2361
2487
  }
2362
2488
  function useStorageStatusSmooth() {
2363
2489
  const room = useRoom();
2364
- const [status, setStatus] = React4.useState(room.getStorageStatus);
2490
+ const [status, setStatus] = React5.useState(room.getStorageStatus);
2365
2491
  const oldStatus = useLatest(room.getStorageStatus());
2366
- React4.useEffect(() => {
2492
+ React5.useEffect(() => {
2367
2493
  let timeoutId;
2368
2494
  const unsub = room.events.storageStatus.subscribe((newStatus) => {
2369
2495
  if (oldStatus.current === "synchronizing" && newStatus === "synchronized") {
@@ -2385,7 +2511,7 @@ function useBatch() {
2385
2511
  }
2386
2512
  function useBroadcastEvent() {
2387
2513
  const room = useRoom();
2388
- return React4.useCallback(
2514
+ return React5.useCallback(
2389
2515
  (event, options = { shouldQueueEventIfNotReady: false }) => {
2390
2516
  room.broadcastEvent(event, options);
2391
2517
  },
@@ -2395,7 +2521,7 @@ function useBroadcastEvent() {
2395
2521
  function useOthersListener(callback) {
2396
2522
  const room = useRoom();
2397
2523
  const savedCallback = useLatest(callback);
2398
- React4.useEffect(
2524
+ React5.useEffect(
2399
2525
  () => room.events.others.subscribe((event) => savedCallback.current(event)),
2400
2526
  [room, savedCallback]
2401
2527
  );
@@ -2403,7 +2529,7 @@ function useOthersListener(callback) {
2403
2529
  function useLostConnectionListener(callback) {
2404
2530
  const room = useRoom();
2405
2531
  const savedCallback = useLatest(callback);
2406
- React4.useEffect(
2532
+ React5.useEffect(
2407
2533
  () => room.events.lostConnection.subscribe(
2408
2534
  (event) => savedCallback.current(event)
2409
2535
  ),
@@ -2413,7 +2539,7 @@ function useLostConnectionListener(callback) {
2413
2539
  function useErrorListener(callback) {
2414
2540
  const room = useRoom();
2415
2541
  const savedCallback = useLatest(callback);
2416
- React4.useEffect(
2542
+ React5.useEffect(
2417
2543
  () => room.events.error.subscribe((e) => savedCallback.current(e)),
2418
2544
  [room, savedCallback]
2419
2545
  );
@@ -2421,7 +2547,7 @@ function useErrorListener(callback) {
2421
2547
  function useEventListener(callback) {
2422
2548
  const room = useRoom();
2423
2549
  const savedCallback = useLatest(callback);
2424
- React4.useEffect(() => {
2550
+ React5.useEffect(() => {
2425
2551
  const listener = (eventData) => {
2426
2552
  savedCallback.current(eventData);
2427
2553
  };
@@ -2454,7 +2580,7 @@ function useSelf(maybeSelector, isEqual) {
2454
2580
  const subscribe = room.events.self.subscribe;
2455
2581
  const getSnapshot = room.getSelf;
2456
2582
  const selector = maybeSelector ?? identity;
2457
- const wrappedSelector = React4.useCallback(
2583
+ const wrappedSelector = React5.useCallback(
2458
2584
  (me) => me !== null ? selector(me) : null,
2459
2585
  [selector]
2460
2586
  );
@@ -2492,11 +2618,11 @@ function useOthers(selector, isEqual) {
2492
2618
  );
2493
2619
  }
2494
2620
  function useOthersMapped(itemSelector, itemIsEqual) {
2495
- const wrappedSelector = React4.useCallback(
2621
+ const wrappedSelector = React5.useCallback(
2496
2622
  (others) => others.map((other) => [other.connectionId, itemSelector(other)]),
2497
2623
  [itemSelector]
2498
2624
  );
2499
- const wrappedIsEqual = React4.useCallback(
2625
+ const wrappedIsEqual = React5.useCallback(
2500
2626
  (a, b) => {
2501
2627
  const eq = itemIsEqual ?? Object.is;
2502
2628
  return a.length === b.length && a.every((atuple, index) => {
@@ -2509,18 +2635,18 @@ function useOthersMapped(itemSelector, itemIsEqual) {
2509
2635
  return useOthers(wrappedSelector, wrappedIsEqual);
2510
2636
  }
2511
2637
  function useOthersConnectionIds() {
2512
- return useOthers(selectorFor_useOthersConnectionIds, shallow2);
2638
+ return useOthers(selectorFor_useOthersConnectionIds, shallow4);
2513
2639
  }
2514
2640
  var NOT_FOUND = Symbol();
2515
2641
  function useOther(connectionId, selector, isEqual) {
2516
- const wrappedSelector = React4.useCallback(
2642
+ const wrappedSelector = React5.useCallback(
2517
2643
  (others) => {
2518
2644
  const other2 = others.find((other3) => other3.connectionId === connectionId);
2519
2645
  return other2 !== void 0 ? selector(other2) : NOT_FOUND;
2520
2646
  },
2521
2647
  [connectionId, selector]
2522
2648
  );
2523
- const wrappedIsEqual = React4.useCallback(
2649
+ const wrappedIsEqual = React5.useCallback(
2524
2650
  (prev, curr) => {
2525
2651
  if (prev === NOT_FOUND || curr === NOT_FOUND) {
2526
2652
  return prev === curr;
@@ -2551,15 +2677,15 @@ function useStorageRoot() {
2551
2677
  function useStorage(selector, isEqual) {
2552
2678
  const room = useRoom();
2553
2679
  const rootOrNull = useMutableStorageRoot();
2554
- const wrappedSelector = React4.useCallback(
2680
+ const wrappedSelector = React5.useCallback(
2555
2681
  (rootOrNull2) => rootOrNull2 !== null ? selector(rootOrNull2) : null,
2556
2682
  [selector]
2557
2683
  );
2558
- const subscribe = React4.useCallback(
2684
+ const subscribe = React5.useCallback(
2559
2685
  (onStoreChange) => rootOrNull !== null ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true }) : noop2,
2560
2686
  [room, rootOrNull]
2561
2687
  );
2562
- const getSnapshot = React4.useCallback(() => {
2688
+ const getSnapshot = React5.useCallback(() => {
2563
2689
  if (rootOrNull === null) {
2564
2690
  return null;
2565
2691
  } else {
@@ -2579,7 +2705,7 @@ function useStorage(selector, isEqual) {
2579
2705
  }
2580
2706
  function useMutation(callback, deps) {
2581
2707
  const room = useRoom();
2582
- return React4.useMemo(
2708
+ return React5.useMemo(
2583
2709
  () => {
2584
2710
  return (...args) => (
2585
2711
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
@@ -2604,16 +2730,16 @@ function useThreads(options = {
2604
2730
  const { scrollOnLoad = true } = options;
2605
2731
  const client = useClient();
2606
2732
  const room = useRoom();
2607
- const queryKey = React4.useMemo(
2733
+ const queryKey = React5.useMemo(
2608
2734
  () => generateQueryKey(room.id, options.query),
2609
2735
  [room, options]
2610
2736
  );
2611
2737
  const { store, getThreadsAndInboxNotifications, incrementQuerySubscribers } = getExtrasForClient2(client);
2612
- React4.useEffect(() => {
2738
+ React5.useEffect(() => {
2613
2739
  void getThreadsAndInboxNotifications(room, queryKey, options);
2614
2740
  return incrementQuerySubscribers(queryKey);
2615
2741
  }, [room, queryKey]);
2616
- const selector = React4.useCallback(
2742
+ const selector = React5.useCallback(
2617
2743
  (state2) => {
2618
2744
  const query = state2.queries[queryKey];
2619
2745
  if (query === void 0 || query.isLoading) {
@@ -2622,7 +2748,11 @@ function useThreads(options = {
2622
2748
  };
2623
2749
  }
2624
2750
  return {
2625
- threads: selectRoomThreads(room.id, state2, options),
2751
+ threads: selectThreads(state2, {
2752
+ roomId: room.id,
2753
+ query: options.query,
2754
+ orderBy: "age"
2755
+ }),
2626
2756
  isLoading: false,
2627
2757
  error: query.error
2628
2758
  };
@@ -2631,9 +2761,9 @@ function useThreads(options = {
2631
2761
  // eslint-disable-line react-hooks/exhaustive-deps
2632
2762
  );
2633
2763
  const state = useSyncExternalStoreWithSelector2(
2634
- store.subscribe,
2635
- store.get,
2636
- store.get,
2764
+ store.subscribeThreads,
2765
+ store.getThreads,
2766
+ store.getThreads,
2637
2767
  selector
2638
2768
  );
2639
2769
  useScrollToCommentOnLoadEffect(scrollOnLoad, state);
@@ -2643,14 +2773,14 @@ function useCommentsErrorListener(callback) {
2643
2773
  const client = useClient();
2644
2774
  const savedCallback = useLatest(callback);
2645
2775
  const { commentsErrorEventSource } = getExtrasForClient2(client);
2646
- React4.useEffect(() => {
2776
+ React5.useEffect(() => {
2647
2777
  return commentsErrorEventSource.subscribe(savedCallback.current);
2648
2778
  }, [savedCallback, commentsErrorEventSource]);
2649
2779
  }
2650
2780
  function useCreateThread() {
2651
2781
  const client = useClient();
2652
2782
  const room = useRoom();
2653
- return React4.useCallback(
2783
+ return React5.useCallback(
2654
2784
  (options) => {
2655
2785
  const body = options.body;
2656
2786
  const metadata = options.metadata ?? {};
@@ -2707,10 +2837,10 @@ function useCreateThread() {
2707
2837
  function useDeleteThread() {
2708
2838
  const client = useClient();
2709
2839
  const room = useRoom();
2710
- return React4.useCallback(
2840
+ return React5.useCallback(
2711
2841
  (threadId) => {
2712
2842
  const { store, onMutationFailure } = getExtrasForClient2(client);
2713
- const thread = store.get().threads[threadId];
2843
+ const thread = store.getThreads().threadsById[threadId];
2714
2844
  const userId = getCurrentUserId(room);
2715
2845
  if (thread?.comments?.[0]?.userId !== userId) {
2716
2846
  throw new Error("Only the thread creator can delete the thread");
@@ -2738,7 +2868,7 @@ function useDeleteThread() {
2738
2868
  function useEditThreadMetadata() {
2739
2869
  const client = useClient();
2740
2870
  const room = useRoom();
2741
- return React4.useCallback(
2871
+ return React5.useCallback(
2742
2872
  (options) => {
2743
2873
  if (!options.metadata) {
2744
2874
  return;
@@ -2756,10 +2886,10 @@ function useEditThreadMetadata() {
2756
2886
  room.editThreadMetadata({ threadId, metadata }).then(
2757
2887
  (metadata2) => (
2758
2888
  // Replace the optimistic update by the real thing
2759
- store.updateThread(
2889
+ store.patchThread(
2760
2890
  threadId,
2761
2891
  optimisticUpdateId,
2762
- (thread) => ({ ...thread, metadata: metadata2 }),
2892
+ { metadata: metadata2 },
2763
2893
  updatedAt
2764
2894
  )
2765
2895
  ),
@@ -2780,7 +2910,7 @@ function useEditThreadMetadata() {
2780
2910
  function useCreateComment() {
2781
2911
  const client = useClient();
2782
2912
  const room = useRoom();
2783
- return React4.useCallback(
2913
+ return React5.useCallback(
2784
2914
  ({ threadId, body }) => {
2785
2915
  const commentId = createCommentId();
2786
2916
  const createdAt = /* @__PURE__ */ new Date();
@@ -2822,11 +2952,11 @@ function useCreateComment() {
2822
2952
  function useEditComment() {
2823
2953
  const client = useClient();
2824
2954
  const room = useRoom();
2825
- return React4.useCallback(
2955
+ return React5.useCallback(
2826
2956
  ({ threadId, commentId, body }) => {
2827
2957
  const editedAt = /* @__PURE__ */ new Date();
2828
2958
  const { store, onMutationFailure } = getExtrasForClient2(client);
2829
- const thread = store.get().threads[threadId];
2959
+ const thread = store.getThreads().threadsById[threadId];
2830
2960
  if (thread === void 0) {
2831
2961
  console3.warn(
2832
2962
  `Internal unexpected behavior. Cannot edit comment in thread "${threadId}" because the thread does not exist in the cache.`
@@ -2852,11 +2982,7 @@ function useEditComment() {
2852
2982
  });
2853
2983
  room.editComment({ threadId, commentId, body }).then(
2854
2984
  (editedComment) => {
2855
- store.updateThread(
2856
- threadId,
2857
- optimisticUpdateId,
2858
- (thread2) => upsertComment(thread2, editedComment)
2859
- );
2985
+ store.editComment(threadId, optimisticUpdateId, editedComment);
2860
2986
  },
2861
2987
  (err) => onMutationFailure(
2862
2988
  err,
@@ -2876,7 +3002,7 @@ function useEditComment() {
2876
3002
  function useDeleteComment() {
2877
3003
  const client = useClient();
2878
3004
  const room = useRoom();
2879
- return React4.useCallback(
3005
+ return React5.useCallback(
2880
3006
  ({ threadId, commentId }) => {
2881
3007
  const deletedAt = /* @__PURE__ */ new Date();
2882
3008
  const { store, onMutationFailure } = getExtrasForClient2(client);
@@ -2889,10 +3015,10 @@ function useDeleteComment() {
2889
3015
  });
2890
3016
  room.deleteComment({ threadId, commentId }).then(
2891
3017
  () => {
2892
- store.updateThread(
3018
+ store.deleteComment(
2893
3019
  threadId,
2894
3020
  optimisticUpdateId,
2895
- (thread) => deleteComment(thread, commentId, deletedAt),
3021
+ commentId,
2896
3022
  deletedAt
2897
3023
  );
2898
3024
  },
@@ -2913,7 +3039,7 @@ function useDeleteComment() {
2913
3039
  function useAddReaction() {
2914
3040
  const client = useClient();
2915
3041
  const room = useRoom();
2916
- return React4.useCallback(
3042
+ return React5.useCallback(
2917
3043
  ({ threadId, commentId, emoji }) => {
2918
3044
  const createdAt = /* @__PURE__ */ new Date();
2919
3045
  const userId = getCurrentUserId(room);
@@ -2930,10 +3056,11 @@ function useAddReaction() {
2930
3056
  });
2931
3057
  room.addReaction({ threadId, commentId, emoji }).then(
2932
3058
  (addedReaction) => {
2933
- store.updateThread(
3059
+ store.addReaction(
2934
3060
  threadId,
2935
3061
  optimisticUpdateId,
2936
- (thread) => addReaction(thread, commentId, addedReaction),
3062
+ commentId,
3063
+ addedReaction,
2937
3064
  createdAt
2938
3065
  );
2939
3066
  },
@@ -2955,7 +3082,7 @@ function useAddReaction() {
2955
3082
  function useRemoveReaction() {
2956
3083
  const client = useClient();
2957
3084
  const room = useRoom();
2958
- return React4.useCallback(
3085
+ return React5.useCallback(
2959
3086
  ({ threadId, commentId, emoji }) => {
2960
3087
  const userId = getCurrentUserId(room);
2961
3088
  const removedAt = /* @__PURE__ */ new Date();
@@ -2970,10 +3097,12 @@ function useRemoveReaction() {
2970
3097
  });
2971
3098
  room.removeReaction({ threadId, commentId, emoji }).then(
2972
3099
  () => {
2973
- store.updateThread(
3100
+ store.removeReaction(
2974
3101
  threadId,
2975
3102
  optimisticUpdateId,
2976
- (thread) => removeReaction(thread, commentId, emoji, userId, removedAt),
3103
+ commentId,
3104
+ emoji,
3105
+ userId,
2977
3106
  removedAt
2978
3107
  );
2979
3108
  },
@@ -2995,11 +3124,11 @@ function useRemoveReaction() {
2995
3124
  function useMarkThreadAsRead() {
2996
3125
  const client = useClient();
2997
3126
  const room = useRoom();
2998
- return React4.useCallback(
3127
+ return React5.useCallback(
2999
3128
  (threadId) => {
3000
3129
  const { store, onMutationFailure } = getExtrasForClient2(client);
3001
3130
  const inboxNotification = Object.values(
3002
- store.get().inboxNotifications
3131
+ store.getInboxNotifications().inboxNotificationsById
3003
3132
  ).find(
3004
3133
  (inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
3005
3134
  );
@@ -3036,7 +3165,7 @@ function useMarkThreadAsRead() {
3036
3165
  function useMarkThreadAsResolved() {
3037
3166
  const client = useClient();
3038
3167
  const room = useRoom();
3039
- return React4.useCallback(
3168
+ return React5.useCallback(
3040
3169
  (threadId) => {
3041
3170
  const updatedAt = /* @__PURE__ */ new Date();
3042
3171
  const { store, onMutationFailure } = getExtrasForClient2(client);
@@ -3047,10 +3176,10 @@ function useMarkThreadAsResolved() {
3047
3176
  });
3048
3177
  room.markThreadAsResolved(threadId).then(
3049
3178
  () => {
3050
- store.updateThread(
3179
+ store.patchThread(
3051
3180
  threadId,
3052
3181
  optimisticUpdateId,
3053
- (thread) => ({ ...thread, resolved: true }),
3182
+ { resolved: true },
3054
3183
  updatedAt
3055
3184
  );
3056
3185
  },
@@ -3070,7 +3199,7 @@ function useMarkThreadAsResolved() {
3070
3199
  function useMarkThreadAsUnresolved() {
3071
3200
  const client = useClient();
3072
3201
  const room = useRoom();
3073
- return React4.useCallback(
3202
+ return React5.useCallback(
3074
3203
  (threadId) => {
3075
3204
  const updatedAt = /* @__PURE__ */ new Date();
3076
3205
  const { store, onMutationFailure } = getExtrasForClient2(client);
@@ -3081,10 +3210,10 @@ function useMarkThreadAsUnresolved() {
3081
3210
  });
3082
3211
  room.markThreadAsUnresolved(threadId).then(
3083
3212
  () => {
3084
- store.updateThread(
3213
+ store.patchThread(
3085
3214
  threadId,
3086
3215
  optimisticUpdateId,
3087
- (thread) => ({ ...thread, resolved: false }),
3216
+ { resolved: false },
3088
3217
  updatedAt
3089
3218
  );
3090
3219
  },
@@ -3104,12 +3233,12 @@ function useMarkThreadAsUnresolved() {
3104
3233
  function useThreadSubscription(threadId) {
3105
3234
  const client = useClient();
3106
3235
  const { store } = getExtrasForClient2(client);
3107
- const selector = React4.useCallback(
3236
+ const selector = React5.useCallback(
3108
3237
  (state) => {
3109
- const inboxNotification = selectInboxNotifications(state).find(
3238
+ const inboxNotification = state.inboxNotifications.find(
3110
3239
  (inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
3111
3240
  );
3112
- const thread = state.threads[threadId];
3241
+ const thread = state.threadsById[threadId];
3113
3242
  if (inboxNotification === void 0 || thread === void 0) {
3114
3243
  return {
3115
3244
  status: "not-subscribed"
@@ -3123,9 +3252,9 @@ function useThreadSubscription(threadId) {
3123
3252
  [threadId]
3124
3253
  );
3125
3254
  return useSyncExternalStoreWithSelector2(
3126
- store.subscribe,
3127
- store.get,
3128
- store.get,
3255
+ store.subscribeThreads,
3256
+ store.getThreads,
3257
+ store.getThreads,
3129
3258
  selector
3130
3259
  );
3131
3260
  }
@@ -3133,13 +3262,13 @@ function useRoomNotificationSettings() {
3133
3262
  const client = useClient();
3134
3263
  const room = useRoom();
3135
3264
  const { store } = getExtrasForClient2(client);
3136
- React4.useEffect(() => {
3265
+ React5.useEffect(() => {
3137
3266
  const { getInboxNotificationSettings } = getExtrasForClient2(client);
3138
3267
  const queryKey = makeNotificationSettingsQueryKey(room.id);
3139
3268
  void getInboxNotificationSettings(room, queryKey);
3140
3269
  }, [client, room]);
3141
3270
  const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
3142
- const selector = React4.useCallback(
3271
+ const selector = React5.useCallback(
3143
3272
  (state) => {
3144
3273
  const query = state.queries[makeNotificationSettingsQueryKey(room.id)];
3145
3274
  if (query === void 0 || query.isLoading) {
@@ -3156,21 +3285,21 @@ function useRoomNotificationSettings() {
3156
3285
  [room]
3157
3286
  );
3158
3287
  const settings = useSyncExternalStoreWithSelector2(
3159
- store.subscribe,
3160
- store.get,
3161
- store.get,
3288
+ store.subscribeNotificationSettings,
3289
+ store.getThreads,
3290
+ store.getThreads,
3162
3291
  selector
3163
3292
  );
3164
- return React4.useMemo(() => {
3293
+ return React5.useMemo(() => {
3165
3294
  return [settings, updateRoomNotificationSettings];
3166
3295
  }, [settings, updateRoomNotificationSettings]);
3167
3296
  }
3168
3297
  function useHistoryVersionData(versionId) {
3169
- const [state, setState] = React4.useState({
3298
+ const [state, setState] = React5.useState({
3170
3299
  isLoading: true
3171
3300
  });
3172
3301
  const room = useRoom();
3173
- React4.useEffect(() => {
3302
+ React5.useEffect(() => {
3174
3303
  setState({ isLoading: true });
3175
3304
  const load = async () => {
3176
3305
  try {
@@ -3199,10 +3328,10 @@ function useHistoryVersions() {
3199
3328
  const room = useRoom();
3200
3329
  const queryKey = getVersionsQueryKey(room.id);
3201
3330
  const { store, getRoomVersions } = getExtrasForClient2(client);
3202
- React4.useEffect(() => {
3331
+ React5.useEffect(() => {
3203
3332
  void getRoomVersions(room);
3204
3333
  }, [room]);
3205
- const selector = React4.useCallback(
3334
+ const selector = React5.useCallback(
3206
3335
  (state2) => {
3207
3336
  const query = state2.queries[queryKey];
3208
3337
  if (query === void 0 || query.isLoading) {
@@ -3211,7 +3340,7 @@ function useHistoryVersions() {
3211
3340
  };
3212
3341
  }
3213
3342
  return {
3214
- versions: state2.versions[room.id],
3343
+ versions: state2.versionsByRoomId[room.id],
3215
3344
  isLoading: false,
3216
3345
  error: query.error
3217
3346
  };
@@ -3220,9 +3349,9 @@ function useHistoryVersions() {
3220
3349
  // eslint-disable-line react-hooks/exhaustive-deps
3221
3350
  );
3222
3351
  const state = useSyncExternalStoreWithSelector2(
3223
- store.subscribe,
3224
- store.get,
3225
- store.get,
3352
+ store.subscribeVersions,
3353
+ store.getVersions,
3354
+ store.getVersions,
3226
3355
  selector
3227
3356
  );
3228
3357
  return state;
@@ -3230,7 +3359,7 @@ function useHistoryVersions() {
3230
3359
  function useUpdateRoomNotificationSettings() {
3231
3360
  const client = useClient();
3232
3361
  const room = useRoom();
3233
- return React4.useCallback(
3362
+ return React5.useCallback(
3234
3363
  (settings) => {
3235
3364
  const { store, onMutationFailure } = getExtrasForClient2(client);
3236
3365
  const optimisticUpdateId = store.addOptimisticUpdate({
@@ -3318,36 +3447,40 @@ function useThreadsSuspense(options = {
3318
3447
  const { scrollOnLoad = true } = options;
3319
3448
  const client = useClient();
3320
3449
  const room = useRoom();
3321
- const queryKey = React4.useMemo(
3450
+ const queryKey = React5.useMemo(
3322
3451
  () => generateQueryKey(room.id, options.query),
3323
3452
  [room, options]
3324
3453
  );
3325
3454
  const { store, getThreadsAndInboxNotifications } = getExtrasForClient2(client);
3326
- const query = store.get().queries[queryKey];
3455
+ const query = store.getThreads().queries[queryKey];
3327
3456
  if (query === void 0 || query.isLoading) {
3328
3457
  throw getThreadsAndInboxNotifications(room, queryKey, options);
3329
3458
  }
3330
3459
  if (query.error) {
3331
3460
  throw query.error;
3332
3461
  }
3333
- const selector = React4.useCallback(
3462
+ const selector = React5.useCallback(
3334
3463
  (state2) => {
3335
3464
  return {
3336
- threads: selectRoomThreads(room.id, state2, options),
3465
+ threads: selectThreads(state2, {
3466
+ roomId: room.id,
3467
+ query: options.query,
3468
+ orderBy: "age"
3469
+ }),
3337
3470
  isLoading: false
3338
3471
  };
3339
3472
  },
3340
3473
  [room, queryKey]
3341
3474
  // eslint-disable-line react-hooks/exhaustive-deps
3342
3475
  );
3343
- React4.useEffect(() => {
3476
+ React5.useEffect(() => {
3344
3477
  const { incrementQuerySubscribers } = getExtrasForClient2(client);
3345
3478
  return incrementQuerySubscribers(queryKey);
3346
3479
  }, [client, queryKey]);
3347
3480
  const state = useSyncExternalStoreWithSelector2(
3348
- store.subscribe,
3349
- store.get,
3350
- store.get,
3481
+ store.subscribeThreads,
3482
+ store.getThreads,
3483
+ store.getThreads,
3351
3484
  selector
3352
3485
  );
3353
3486
  useScrollToCommentOnLoadEffect(scrollOnLoad, state);
@@ -3358,17 +3491,17 @@ function useHistoryVersionsSuspense() {
3358
3491
  const room = useRoom();
3359
3492
  const queryKey = getVersionsQueryKey(room.id);
3360
3493
  const { store, getRoomVersions } = getExtrasForClient2(client);
3361
- const query = store.get().queries[queryKey];
3494
+ const query = store.getVersions().queries[queryKey];
3362
3495
  if (query === void 0 || query.isLoading) {
3363
3496
  throw getRoomVersions(room);
3364
3497
  }
3365
3498
  if (query.error) {
3366
3499
  throw query.error;
3367
3500
  }
3368
- const selector = React4.useCallback(
3501
+ const selector = React5.useCallback(
3369
3502
  (state2) => {
3370
3503
  return {
3371
- versions: state2.versions[room.id],
3504
+ versions: state2.versionsByRoomId[room.id],
3372
3505
  isLoading: false
3373
3506
  };
3374
3507
  },
@@ -3376,9 +3509,9 @@ function useHistoryVersionsSuspense() {
3376
3509
  // eslint-disable-line react-hooks/exhaustive-deps
3377
3510
  );
3378
3511
  const state = useSyncExternalStoreWithSelector2(
3379
- store.subscribe,
3380
- store.get,
3381
- store.get,
3512
+ store.subscribeVersions,
3513
+ store.getVersions,
3514
+ store.getVersions,
3382
3515
  selector
3383
3516
  );
3384
3517
  return state;
@@ -3389,14 +3522,14 @@ function useRoomNotificationSettingsSuspense() {
3389
3522
  const room = useRoom();
3390
3523
  const queryKey = makeNotificationSettingsQueryKey(room.id);
3391
3524
  const { store, getInboxNotificationSettings } = getExtrasForClient2(client);
3392
- const query = store.get().queries[queryKey];
3525
+ const query = store.getNotificationSettings().queries[queryKey];
3393
3526
  if (query === void 0 || query.isLoading) {
3394
3527
  throw getInboxNotificationSettings(room, queryKey);
3395
3528
  }
3396
3529
  if (query.error) {
3397
3530
  throw query.error;
3398
3531
  }
3399
- const selector = React4.useCallback(
3532
+ const selector = React5.useCallback(
3400
3533
  (state) => {
3401
3534
  return {
3402
3535
  isLoading: false,
@@ -3406,18 +3539,15 @@ function useRoomNotificationSettingsSuspense() {
3406
3539
  [room]
3407
3540
  );
3408
3541
  const settings = useSyncExternalStoreWithSelector2(
3409
- store.subscribe,
3410
- store.get,
3411
- store.get,
3542
+ store.subscribeNotificationSettings,
3543
+ store.getNotificationSettings,
3544
+ store.getNotificationSettings,
3412
3545
  selector
3413
3546
  );
3414
- return React4.useMemo(() => {
3547
+ return React5.useMemo(() => {
3415
3548
  return [settings, updateRoomNotificationSettings];
3416
3549
  }, [settings, updateRoomNotificationSettings]);
3417
3550
  }
3418
- function useRoomOrNull() {
3419
- return React4.useContext(RoomContext);
3420
- }
3421
3551
  function createRoomContext(client) {
3422
3552
  return getOrCreateRoomContextBundle(client);
3423
3553
  }
@@ -3469,9 +3599,29 @@ export {
3469
3599
  PKG_VERSION,
3470
3600
  PKG_FORMAT,
3471
3601
  ClientSideSuspense,
3472
- CreateThreadError,
3473
- selectRoomThreads,
3474
3602
  RoomContext,
3603
+ ClientContext,
3604
+ selectThreads,
3605
+ getUmbrellaStoreForClient,
3606
+ useClient,
3607
+ LiveblocksProvider,
3608
+ createLiveblocksContext,
3609
+ useInboxNotifications,
3610
+ useInboxNotificationsSuspense,
3611
+ useMarkAllInboxNotificationsAsRead,
3612
+ useMarkInboxNotificationAsRead,
3613
+ useDeleteAllInboxNotifications,
3614
+ useDeleteInboxNotification,
3615
+ useUnreadInboxNotificationsCount,
3616
+ useUnreadInboxNotificationsCountSuspense,
3617
+ useRoomInfo,
3618
+ useRoomInfoSuspense,
3619
+ _useInboxNotificationThread,
3620
+ _useUser,
3621
+ _useUserSuspense,
3622
+ _useUserThreads_experimental,
3623
+ _useUserThreadsSuspense_experimental,
3624
+ CreateThreadError,
3475
3625
  useStatus,
3476
3626
  useStorageStatus,
3477
3627
  useBatch,
@@ -3525,26 +3675,6 @@ export {
3525
3675
  _useSelf,
3526
3676
  _useSelfSuspense,
3527
3677
  _useStorageRoot,
3528
- _useUpdateMyPresence,
3529
- ClientContext,
3530
- getUmbrellaStoreForClient,
3531
- useClient,
3532
- LiveblocksProvider,
3533
- createLiveblocksContext,
3534
- useInboxNotifications,
3535
- useInboxNotificationsSuspense,
3536
- useMarkAllInboxNotificationsAsRead,
3537
- useMarkInboxNotificationAsRead,
3538
- useDeleteAllInboxNotifications,
3539
- useDeleteInboxNotification,
3540
- useUnreadInboxNotificationsCount,
3541
- useUnreadInboxNotificationsCountSuspense,
3542
- useRoomInfo,
3543
- useRoomInfoSuspense,
3544
- _useInboxNotificationThread,
3545
- _useUser,
3546
- _useUserSuspense,
3547
- _useUserThreads_experimental,
3548
- _useUserThreadsSuspense_experimental
3678
+ _useUpdateMyPresence
3549
3679
  };
3550
- //# sourceMappingURL=chunk-OKR7ROQ5.mjs.map
3680
+ //# sourceMappingURL=chunk-XK5NTOJJ.mjs.map