@liveblocks/react 2.7.0-versions2 → 2.7.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.
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/version.ts
2
2
  var PKG_NAME = "@liveblocks/react";
3
- var PKG_VERSION = "2.7.0-versions2";
3
+ var PKG_VERSION = "2.7.0";
4
4
  var PKG_FORMAT = "cjs";
5
5
 
6
6
  // src/ClientSideSuspense.tsx
@@ -13,65 +13,6 @@ 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/lib/selected-threads.ts
17
-
18
-
19
- var _core = require('@liveblocks/core');
20
- function selectedUserThreads(state) {
21
- const result = _core.applyOptimisticUpdates.call(void 0, state);
22
- const threads = Object.values(result.threads).filter(
23
- (thread) => {
24
- if (thread.deletedAt !== void 0) {
25
- return false;
26
- }
27
- return true;
28
- }
29
- );
30
- return threads.sort(
31
- (a, b) => (_nullishCoalesce(b.updatedAt, () => ( b.createdAt))).getTime() - (_nullishCoalesce(a.updatedAt, () => ( a.createdAt))).getTime()
32
- );
33
- }
34
- function selectedThreads(roomId, state, options) {
35
- const result = _core.applyOptimisticUpdates.call(void 0, state);
36
- const threads = Object.values(result.threads).filter(
37
- (thread) => {
38
- if (thread.roomId !== roomId) return false;
39
- if (thread.deletedAt !== void 0) {
40
- return false;
41
- }
42
- const query = options.query;
43
- if (!query) return true;
44
- if (query.resolved !== void 0 && thread.resolved !== query.resolved) {
45
- return false;
46
- }
47
- for (const key in query.metadata) {
48
- const metadataValue = thread.metadata[key];
49
- const filterValue = query.metadata[key];
50
- if (assertFilterIsStartsWithOperator(filterValue) && assertMetadataValueIsString(metadataValue)) {
51
- if (metadataValue.startsWith(filterValue.startsWith)) {
52
- return true;
53
- }
54
- }
55
- if (metadataValue !== filterValue) {
56
- return false;
57
- }
58
- }
59
- return true;
60
- }
61
- );
62
- return threads.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
63
- }
64
- var assertFilterIsStartsWithOperator = (filter) => {
65
- if (typeof filter === "object" && typeof filter.startsWith === "string") {
66
- return true;
67
- } else {
68
- return false;
69
- }
70
- };
71
- var assertMetadataValueIsString = (value) => {
72
- return typeof value === "string";
73
- };
74
-
75
16
  // src/comments/errors.ts
76
17
  var CreateThreadError = class extends Error {
77
18
  constructor(cause, context) {
@@ -186,33 +127,53 @@ var _client = require('@liveblocks/client');
186
127
 
187
128
 
188
129
 
189
-
190
-
191
-
192
-
193
-
130
+ var _core = require('@liveblocks/core');
194
131
 
195
132
  var _withselectorjs = require('use-sync-external-store/shim/with-selector.js');
196
133
 
197
- // src/comments/lib/select-notification-settings.ts
198
-
199
-
134
+ // src/lib/compare.ts
135
+ function byFirstCreated(a, b) {
136
+ return a.createdAt.getTime() - b.createdAt.getTime();
137
+ }
138
+ function isMoreRecentlyUpdated(a, b) {
139
+ return byMostRecentlyUpdated(a, b) < 0;
140
+ }
141
+ function byMostRecentlyUpdated(a, b) {
142
+ return (_nullishCoalesce(b.updatedAt, () => ( b.createdAt))).getTime() - (_nullishCoalesce(a.updatedAt, () => ( a.createdAt))).getTime();
143
+ }
200
144
 
145
+ // src/lib/guards.ts
201
146
 
202
- function selectNotificationSettings(roomId, state) {
203
- const { notificationSettings } = _core.applyOptimisticUpdates.call(void 0, state);
204
- return _core.nn.call(void 0, notificationSettings[roomId]);
147
+ function isStartsWith(blob) {
148
+ return _core.isPlainObject.call(void 0, blob) && isString(blob.startsWith);
149
+ }
150
+ function isString(value) {
151
+ return typeof value === "string";
205
152
  }
206
153
 
207
- // src/comments/lib/selected-inbox-notifications.ts
208
-
209
- function selectedInboxNotifications(state) {
210
- const result = _core.applyOptimisticUpdates.call(void 0, state);
211
- return Object.values(result.inboxNotifications).sort(
212
- // Sort so that the most recent notifications are first
213
- (a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime()
154
+ // src/lib/querying.ts
155
+ function makeThreadsFilter(query) {
156
+ return (thread) => matchesQuery(thread, query) && matchesMetadata(thread, query);
157
+ }
158
+ function matchesQuery(thread, q) {
159
+ return q.resolved === void 0 || thread.resolved === q.resolved;
160
+ }
161
+ function matchesMetadata(thread, q) {
162
+ const metadata = thread.metadata;
163
+ return q.metadata === void 0 || Object.entries(q.metadata).every(
164
+ ([key, op]) => (
165
+ // Boolean logic: op? => value matches the operator
166
+ op === void 0 || matchesOperator(metadata[key], op)
167
+ )
214
168
  );
215
169
  }
170
+ function matchesOperator(value, op) {
171
+ if (isStartsWith(op)) {
172
+ return isString(value) && value.startsWith(op.startsWith);
173
+ } else {
174
+ return value === op;
175
+ }
176
+ }
216
177
 
217
178
  // src/lib/retry-error.ts
218
179
 
@@ -320,6 +281,709 @@ var use = (
320
281
 
321
282
  var _indexjs = require('use-sync-external-store/shim/index.js');
322
283
 
284
+
285
+ // src/umbrella-store.ts
286
+
287
+ var UmbrellaStore = class {
288
+ constructor() {
289
+ this._store = _core.createStore.call(void 0, {
290
+ threads: {},
291
+ queries: {},
292
+ optimisticUpdates: [],
293
+ inboxNotifications: {},
294
+ notificationSettings: {},
295
+ versions: {}
296
+ });
297
+ this.get = this.get.bind(this);
298
+ this.subscribe = this.subscribe.bind(this);
299
+ }
300
+ get() {
301
+ return this._store.get();
302
+ }
303
+ subscribe(callback) {
304
+ return this._store.subscribe(callback);
305
+ }
306
+ // Direct low-level cache mutations ------------------------------------------------- {{{
307
+ updateThreadsCache(mapFn) {
308
+ this._store.set((state) => {
309
+ const threads = mapFn(state.threads);
310
+ return threads !== state.threads ? { ...state, threads } : state;
311
+ });
312
+ }
313
+ updateInboxNotificationsCache(mapFn) {
314
+ this._store.set((state) => {
315
+ const inboxNotifications = mapFn(state.inboxNotifications);
316
+ return inboxNotifications !== state.inboxNotifications ? { ...state, inboxNotifications } : state;
317
+ });
318
+ }
319
+ setNotificationSettings(roomId, settings) {
320
+ this._store.set((state) => ({
321
+ ...state,
322
+ notificationSettings: {
323
+ ...state.notificationSettings,
324
+ [roomId]: settings
325
+ }
326
+ }));
327
+ }
328
+ setVersions(roomId, versions) {
329
+ this._store.set((state) => ({
330
+ ...state,
331
+ versions: {
332
+ ...state.versions,
333
+ [roomId]: versions
334
+ }
335
+ }));
336
+ }
337
+ setQueryState(queryKey, queryState) {
338
+ this._store.set((state) => ({
339
+ ...state,
340
+ queries: {
341
+ ...state.queries,
342
+ [queryKey]: queryState
343
+ }
344
+ }));
345
+ }
346
+ updateOptimisticUpdatesCache(mapFn) {
347
+ this._store.set((state) => ({
348
+ ...state,
349
+ optimisticUpdates: mapFn(state.optimisticUpdates)
350
+ }));
351
+ }
352
+ // ---------------------------------------------------------------------------------- }}}
353
+ /** @internal - Only call this method from unit tests. */
354
+ force_set(callback) {
355
+ return this._store.set(callback);
356
+ }
357
+ /**
358
+ * Updates an existing inbox notification with a new value, replacing the
359
+ * corresponding optimistic update.
360
+ *
361
+ * This will not update anything if the inbox notification ID isn't found in
362
+ * the cache.
363
+ */
364
+ updateInboxNotification(inboxNotificationId, optimisticUpdateId, callback) {
365
+ this._store.batch(() => {
366
+ this.removeOptimisticUpdate(optimisticUpdateId);
367
+ this.updateInboxNotificationsCache((cache) => {
368
+ const existing = cache[inboxNotificationId];
369
+ if (!existing) {
370
+ return cache;
371
+ }
372
+ const inboxNotifications = {
373
+ ...cache,
374
+ [inboxNotificationId]: callback(existing)
375
+ };
376
+ return inboxNotifications;
377
+ });
378
+ });
379
+ }
380
+ /**
381
+ * Updates *all* inbox notifications by running a mapper function over all of
382
+ * them, replacing the corresponding optimistic update.
383
+ */
384
+ updateAllInboxNotifications(optimisticUpdateId, mapFn) {
385
+ this._store.batch(() => {
386
+ this.removeOptimisticUpdate(optimisticUpdateId);
387
+ this.updateInboxNotificationsCache((cache) => _core.mapValues.call(void 0, cache, mapFn));
388
+ });
389
+ }
390
+ /**
391
+ * Deletes an existing inbox notification, replacing the corresponding
392
+ * optimistic update.
393
+ */
394
+ deleteInboxNotification(inboxNotificationId, optimisticUpdateId) {
395
+ this._store.batch(() => {
396
+ this.removeOptimisticUpdate(optimisticUpdateId);
397
+ this.updateInboxNotificationsCache((cache) => {
398
+ const { [inboxNotificationId]: removed, ...newCache } = cache;
399
+ return removed === void 0 ? cache : newCache;
400
+ });
401
+ });
402
+ }
403
+ /**
404
+ * Deletes *all* inbox notifications, replacing the corresponding optimistic
405
+ * update.
406
+ */
407
+ deleteAllInboxNotifications(optimisticUpdateId) {
408
+ this._store.batch(() => {
409
+ this.removeOptimisticUpdate(optimisticUpdateId);
410
+ this.updateInboxNotificationsCache(() => ({}));
411
+ });
412
+ }
413
+ /**
414
+ * Creates an new thread, replacing the corresponding optimistic update.
415
+ */
416
+ createThread(optimisticUpdateId, thread) {
417
+ this._store.batch(() => {
418
+ this.removeOptimisticUpdate(optimisticUpdateId);
419
+ this.updateThreadsCache((cache) => ({ ...cache, [thread.id]: thread }));
420
+ });
421
+ }
422
+ /**
423
+ * Updates an existing thread with a new value, replacing the corresponding
424
+ * optimistic update.
425
+ *
426
+ * This will not update anything if:
427
+ * - The thread ID isn't found in the cache; or
428
+ * - The thread ID was already deleted from the cache; or
429
+ * - The thread ID in the cache was updated more recently than the optimistic
430
+ * update's timestamp (if given)
431
+ */
432
+ updateThread(threadId, optimisticUpdateId, callback, updatedAt) {
433
+ this._store.batch(() => {
434
+ if (optimisticUpdateId !== null) {
435
+ this.removeOptimisticUpdate(optimisticUpdateId);
436
+ }
437
+ this.updateThreadsCache((cache) => {
438
+ const existing = cache[threadId];
439
+ if (!existing) {
440
+ return cache;
441
+ }
442
+ if (existing.deletedAt !== void 0) {
443
+ return cache;
444
+ }
445
+ if (!!updatedAt && !!existing.updatedAt && existing.updatedAt > updatedAt) {
446
+ return cache;
447
+ }
448
+ return { ...cache, [threadId]: callback(existing) };
449
+ });
450
+ });
451
+ }
452
+ /**
453
+ * Soft-deletes an existing thread by setting its `deletedAt` value,
454
+ * replacing the corresponding optimistic update.
455
+ *
456
+ * This will not update anything if:
457
+ * - The thread ID isn't found in the cache; or
458
+ * - The thread ID was already deleted from the cache
459
+ */
460
+ deleteThread(threadId, optimisticUpdateId) {
461
+ return this.updateThread(
462
+ threadId,
463
+ optimisticUpdateId,
464
+ // A deletion is actually an update of the deletedAt property internally
465
+ (thread) => ({ ...thread, updatedAt: /* @__PURE__ */ new Date(), deletedAt: /* @__PURE__ */ new Date() })
466
+ );
467
+ }
468
+ /**
469
+ * Creates an existing comment and ensures the associated notification is
470
+ * updated correctly, replacing the corresponding optimistic update.
471
+ */
472
+ createComment(newComment, optimisticUpdateId) {
473
+ this._store.batch(() => {
474
+ this.removeOptimisticUpdate(optimisticUpdateId);
475
+ const existingThread = this._store.get().threads[newComment.threadId];
476
+ if (!existingThread) {
477
+ return;
478
+ }
479
+ this.updateThreadsCache((cache) => ({
480
+ ...cache,
481
+ [newComment.threadId]: upsertComment(existingThread, newComment)
482
+ }));
483
+ this.updateInboxNotificationsCache((cache) => {
484
+ const existingNotification = Object.values(cache).find(
485
+ (notification) => notification.kind === "thread" && notification.threadId === newComment.threadId
486
+ );
487
+ if (!existingNotification) {
488
+ return cache;
489
+ }
490
+ return {
491
+ ...cache,
492
+ [existingNotification.id]: {
493
+ ...existingNotification,
494
+ notifiedAt: newComment.createdAt,
495
+ readAt: newComment.createdAt
496
+ }
497
+ };
498
+ });
499
+ });
500
+ }
501
+ updateThreadAndNotification(thread, inboxNotification) {
502
+ this._store.batch(() => {
503
+ this.updateThreadsCache((cache) => {
504
+ const existingThread = cache[thread.id];
505
+ return existingThread === void 0 || isMoreRecentlyUpdated(thread, existingThread) ? { ...cache, [thread.id]: thread } : cache;
506
+ });
507
+ if (inboxNotification !== void 0) {
508
+ this.updateInboxNotificationsCache((cache) => ({
509
+ ...cache,
510
+ [inboxNotification.id]: inboxNotification
511
+ }));
512
+ }
513
+ });
514
+ }
515
+ updateThreadsAndNotifications(threads, inboxNotifications, deletedThreads, deletedInboxNotifications, queryKey) {
516
+ this._store.batch(() => {
517
+ this.updateThreadsCache(
518
+ (cache) => applyThreadUpdates(cache, {
519
+ newThreads: threads,
520
+ deletedThreads
521
+ })
522
+ );
523
+ this.updateInboxNotificationsCache(
524
+ (cache) => applyNotificationsUpdates(cache, {
525
+ newInboxNotifications: inboxNotifications,
526
+ deletedNotifications: deletedInboxNotifications
527
+ })
528
+ );
529
+ if (queryKey !== void 0) {
530
+ this.setQueryOK(queryKey);
531
+ }
532
+ });
533
+ }
534
+ /**
535
+ * Updates existing notification setting for a room with a new value,
536
+ * replacing the corresponding optimistic update.
537
+ */
538
+ updateRoomInboxNotificationSettings2(roomId, optimisticUpdateId, settings) {
539
+ this._store.batch(() => {
540
+ this.removeOptimisticUpdate(optimisticUpdateId);
541
+ this.setNotificationSettings(roomId, settings);
542
+ });
543
+ }
544
+ updateRoomInboxNotificationSettings(roomId, settings, queryKey) {
545
+ this._store.batch(() => {
546
+ this.setQueryOK(queryKey);
547
+ this.setNotificationSettings(roomId, settings);
548
+ });
549
+ }
550
+ updateRoomVersions(roomId, versions, queryKey) {
551
+ this._store.batch(() => {
552
+ this.setVersions(roomId, versions);
553
+ if (queryKey !== void 0) {
554
+ this.setQueryOK(queryKey);
555
+ }
556
+ });
557
+ }
558
+ addOptimisticUpdate(optimisticUpdate) {
559
+ const id = _core.nanoid.call(void 0, );
560
+ const newUpdate = { ...optimisticUpdate, id };
561
+ this.updateOptimisticUpdatesCache((cache) => [...cache, newUpdate]);
562
+ return id;
563
+ }
564
+ removeOptimisticUpdate(optimisticUpdateId) {
565
+ this.updateOptimisticUpdatesCache(
566
+ (cache) => cache.filter((ou) => ou.id !== optimisticUpdateId)
567
+ );
568
+ }
569
+ //
570
+ // Query State APIs
571
+ //
572
+ setQueryLoading(queryKey) {
573
+ this.setQueryState(queryKey, { isLoading: true });
574
+ }
575
+ setQueryOK(queryKey) {
576
+ this.setQueryState(queryKey, { isLoading: false, data: void 0 });
577
+ }
578
+ setQueryError(queryKey, error) {
579
+ this.setQueryState(queryKey, { isLoading: false, error });
580
+ }
581
+ };
582
+ function applyOptimisticUpdates(state) {
583
+ const result = {
584
+ threads: {
585
+ ...state.threads
586
+ },
587
+ inboxNotifications: {
588
+ ...state.inboxNotifications
589
+ },
590
+ notificationSettings: {
591
+ ...state.notificationSettings
592
+ }
593
+ };
594
+ for (const optimisticUpdate of state.optimisticUpdates) {
595
+ switch (optimisticUpdate.type) {
596
+ case "create-thread": {
597
+ result.threads[optimisticUpdate.thread.id] = optimisticUpdate.thread;
598
+ break;
599
+ }
600
+ case "edit-thread-metadata": {
601
+ const thread = result.threads[optimisticUpdate.threadId];
602
+ if (thread === void 0) {
603
+ break;
604
+ }
605
+ if (thread.deletedAt !== void 0) {
606
+ break;
607
+ }
608
+ if (thread.updatedAt !== void 0 && thread.updatedAt > optimisticUpdate.updatedAt) {
609
+ break;
610
+ }
611
+ result.threads[thread.id] = {
612
+ ...thread,
613
+ updatedAt: optimisticUpdate.updatedAt,
614
+ metadata: {
615
+ ...thread.metadata,
616
+ ...optimisticUpdate.metadata
617
+ }
618
+ };
619
+ break;
620
+ }
621
+ case "mark-thread-as-resolved": {
622
+ const thread = result.threads[optimisticUpdate.threadId];
623
+ if (thread === void 0) {
624
+ break;
625
+ }
626
+ if (thread.deletedAt !== void 0) {
627
+ break;
628
+ }
629
+ result.threads[thread.id] = {
630
+ ...thread,
631
+ resolved: true
632
+ };
633
+ break;
634
+ }
635
+ case "mark-thread-as-unresolved": {
636
+ const thread = result.threads[optimisticUpdate.threadId];
637
+ if (thread === void 0) {
638
+ break;
639
+ }
640
+ if (thread.deletedAt !== void 0) {
641
+ break;
642
+ }
643
+ result.threads[thread.id] = {
644
+ ...thread,
645
+ resolved: false
646
+ };
647
+ break;
648
+ }
649
+ case "create-comment": {
650
+ const thread = result.threads[optimisticUpdate.comment.threadId];
651
+ if (thread === void 0) {
652
+ break;
653
+ }
654
+ result.threads[thread.id] = upsertComment(
655
+ thread,
656
+ optimisticUpdate.comment
657
+ );
658
+ const inboxNotification = Object.values(result.inboxNotifications).find(
659
+ (notification) => notification.kind === "thread" && notification.threadId === thread.id
660
+ );
661
+ if (inboxNotification === void 0) {
662
+ break;
663
+ }
664
+ result.inboxNotifications[inboxNotification.id] = {
665
+ ...inboxNotification,
666
+ notifiedAt: optimisticUpdate.comment.createdAt,
667
+ readAt: optimisticUpdate.comment.createdAt
668
+ };
669
+ break;
670
+ }
671
+ case "edit-comment": {
672
+ const thread = result.threads[optimisticUpdate.comment.threadId];
673
+ if (thread === void 0) {
674
+ break;
675
+ }
676
+ result.threads[thread.id] = upsertComment(
677
+ thread,
678
+ optimisticUpdate.comment
679
+ );
680
+ break;
681
+ }
682
+ case "delete-comment": {
683
+ const thread = result.threads[optimisticUpdate.threadId];
684
+ if (thread === void 0) {
685
+ break;
686
+ }
687
+ result.threads[thread.id] = deleteComment(
688
+ thread,
689
+ optimisticUpdate.commentId,
690
+ optimisticUpdate.deletedAt
691
+ );
692
+ break;
693
+ }
694
+ case "delete-thread": {
695
+ const thread = result.threads[optimisticUpdate.threadId];
696
+ if (thread === void 0) {
697
+ break;
698
+ }
699
+ result.threads[optimisticUpdate.threadId] = {
700
+ ...result.threads[optimisticUpdate.threadId],
701
+ deletedAt: optimisticUpdate.deletedAt,
702
+ updatedAt: optimisticUpdate.deletedAt,
703
+ comments: []
704
+ };
705
+ break;
706
+ }
707
+ case "add-reaction": {
708
+ const thread = result.threads[optimisticUpdate.threadId];
709
+ if (thread === void 0) {
710
+ break;
711
+ }
712
+ result.threads[thread.id] = addReaction(
713
+ thread,
714
+ optimisticUpdate.commentId,
715
+ optimisticUpdate.reaction
716
+ );
717
+ break;
718
+ }
719
+ case "remove-reaction": {
720
+ const thread = result.threads[optimisticUpdate.threadId];
721
+ if (thread === void 0) {
722
+ break;
723
+ }
724
+ result.threads[thread.id] = removeReaction(
725
+ thread,
726
+ optimisticUpdate.commentId,
727
+ optimisticUpdate.emoji,
728
+ optimisticUpdate.userId,
729
+ optimisticUpdate.removedAt
730
+ );
731
+ break;
732
+ }
733
+ case "mark-inbox-notification-as-read": {
734
+ result.inboxNotifications[optimisticUpdate.inboxNotificationId] = {
735
+ ...state.inboxNotifications[optimisticUpdate.inboxNotificationId],
736
+ readAt: optimisticUpdate.readAt
737
+ };
738
+ break;
739
+ }
740
+ case "mark-all-inbox-notifications-as-read": {
741
+ for (const id in result.inboxNotifications) {
742
+ result.inboxNotifications[id] = {
743
+ ...result.inboxNotifications[id],
744
+ readAt: optimisticUpdate.readAt
745
+ };
746
+ }
747
+ break;
748
+ }
749
+ case "delete-inbox-notification": {
750
+ const {
751
+ [optimisticUpdate.inboxNotificationId]: _,
752
+ ...inboxNotifications
753
+ } = result.inboxNotifications;
754
+ result.inboxNotifications = inboxNotifications;
755
+ break;
756
+ }
757
+ case "delete-all-inbox-notifications": {
758
+ result.inboxNotifications = {};
759
+ break;
760
+ }
761
+ case "update-notification-settings": {
762
+ result.notificationSettings[optimisticUpdate.roomId] = {
763
+ ...result.notificationSettings[optimisticUpdate.roomId],
764
+ ...optimisticUpdate.settings
765
+ };
766
+ }
767
+ }
768
+ }
769
+ return result;
770
+ }
771
+ function applyThreadUpdates(existingThreads, updates) {
772
+ const updatedThreads = { ...existingThreads };
773
+ updates.newThreads.forEach((thread) => {
774
+ const existingThread = updatedThreads[thread.id];
775
+ if (existingThread) {
776
+ if (isMoreRecentlyUpdated(existingThread, thread)) {
777
+ return;
778
+ }
779
+ }
780
+ updatedThreads[thread.id] = thread;
781
+ });
782
+ updates.deletedThreads.forEach(({ id, deletedAt }) => {
783
+ const existingThread = updatedThreads[id];
784
+ if (existingThread === void 0) return;
785
+ existingThread.deletedAt = deletedAt;
786
+ existingThread.updatedAt = deletedAt;
787
+ existingThread.comments = [];
788
+ });
789
+ return updatedThreads;
790
+ }
791
+ function applyNotificationsUpdates(existingInboxNotifications, updates) {
792
+ const updatedInboxNotifications = { ...existingInboxNotifications };
793
+ updates.newInboxNotifications.forEach((notification) => {
794
+ const existingNotification = updatedInboxNotifications[notification.id];
795
+ if (existingNotification) {
796
+ const result = compareInboxNotifications(
797
+ existingNotification,
798
+ notification
799
+ );
800
+ if (result === 1) return;
801
+ }
802
+ updatedInboxNotifications[notification.id] = notification;
803
+ });
804
+ updates.deletedNotifications.forEach(
805
+ ({ id }) => delete updatedInboxNotifications[id]
806
+ );
807
+ return updatedInboxNotifications;
808
+ }
809
+ function compareInboxNotifications(inboxNotificationA, inboxNotificationB) {
810
+ if (inboxNotificationA.notifiedAt > inboxNotificationB.notifiedAt) {
811
+ return 1;
812
+ } else if (inboxNotificationA.notifiedAt < inboxNotificationB.notifiedAt) {
813
+ return -1;
814
+ }
815
+ if (inboxNotificationA.readAt && inboxNotificationB.readAt) {
816
+ return inboxNotificationA.readAt > inboxNotificationB.readAt ? 1 : inboxNotificationA.readAt < inboxNotificationB.readAt ? -1 : 0;
817
+ } else if (inboxNotificationA.readAt || inboxNotificationB.readAt) {
818
+ return inboxNotificationA.readAt ? 1 : -1;
819
+ }
820
+ return 0;
821
+ }
822
+ function upsertComment(thread, comment) {
823
+ if (thread.deletedAt !== void 0) {
824
+ return thread;
825
+ }
826
+ if (comment.threadId !== thread.id) {
827
+ _core.console.warn(
828
+ `Comment ${comment.id} does not belong to thread ${thread.id}`
829
+ );
830
+ return thread;
831
+ }
832
+ const existingComment = thread.comments.find(
833
+ (existingComment2) => existingComment2.id === comment.id
834
+ );
835
+ if (existingComment === void 0) {
836
+ const updatedAt = new Date(
837
+ Math.max(_optionalChain([thread, 'access', _2 => _2.updatedAt, 'optionalAccess', _3 => _3.getTime, 'call', _4 => _4()]) || 0, comment.createdAt.getTime())
838
+ );
839
+ const updatedThread = {
840
+ ...thread,
841
+ updatedAt,
842
+ comments: [...thread.comments, comment]
843
+ };
844
+ return updatedThread;
845
+ }
846
+ if (existingComment.deletedAt !== void 0) {
847
+ return thread;
848
+ }
849
+ if (existingComment.editedAt === void 0 || comment.editedAt === void 0 || existingComment.editedAt <= comment.editedAt) {
850
+ const updatedComments = thread.comments.map(
851
+ (existingComment2) => existingComment2.id === comment.id ? comment : existingComment2
852
+ );
853
+ const updatedThread = {
854
+ ...thread,
855
+ updatedAt: new Date(
856
+ Math.max(
857
+ _optionalChain([thread, 'access', _5 => _5.updatedAt, 'optionalAccess', _6 => _6.getTime, 'call', _7 => _7()]) || 0,
858
+ _optionalChain([comment, 'access', _8 => _8.editedAt, 'optionalAccess', _9 => _9.getTime, 'call', _10 => _10()]) || comment.createdAt.getTime()
859
+ )
860
+ ),
861
+ comments: updatedComments
862
+ };
863
+ return updatedThread;
864
+ }
865
+ return thread;
866
+ }
867
+ function deleteComment(thread, commentId, deletedAt) {
868
+ if (thread.deletedAt !== void 0) {
869
+ return thread;
870
+ }
871
+ const existingComment = thread.comments.find(
872
+ (comment) => comment.id === commentId
873
+ );
874
+ if (existingComment === void 0) {
875
+ return thread;
876
+ }
877
+ if (existingComment.deletedAt !== void 0) {
878
+ return thread;
879
+ }
880
+ const updatedComments = thread.comments.map(
881
+ (comment) => comment.id === commentId ? {
882
+ ...comment,
883
+ deletedAt,
884
+ body: void 0
885
+ } : comment
886
+ );
887
+ if (!updatedComments.some((comment) => comment.deletedAt === void 0)) {
888
+ return {
889
+ ...thread,
890
+ deletedAt,
891
+ updatedAt: deletedAt,
892
+ comments: []
893
+ };
894
+ }
895
+ return {
896
+ ...thread,
897
+ updatedAt: deletedAt,
898
+ comments: updatedComments
899
+ };
900
+ }
901
+ function addReaction(thread, commentId, reaction) {
902
+ if (thread.deletedAt !== void 0) {
903
+ return thread;
904
+ }
905
+ const existingComment = thread.comments.find(
906
+ (comment) => comment.id === commentId
907
+ );
908
+ if (existingComment === void 0) {
909
+ return thread;
910
+ }
911
+ if (existingComment.deletedAt !== void 0) {
912
+ return thread;
913
+ }
914
+ const updatedComments = thread.comments.map(
915
+ (comment) => comment.id === commentId ? {
916
+ ...comment,
917
+ reactions: upsertReaction(comment.reactions, reaction)
918
+ } : comment
919
+ );
920
+ return {
921
+ ...thread,
922
+ updatedAt: new Date(
923
+ Math.max(reaction.createdAt.getTime(), _optionalChain([thread, 'access', _11 => _11.updatedAt, 'optionalAccess', _12 => _12.getTime, 'call', _13 => _13()]) || 0)
924
+ ),
925
+ comments: updatedComments
926
+ };
927
+ }
928
+ function removeReaction(thread, commentId, emoji, userId, removedAt) {
929
+ if (thread.deletedAt !== void 0) {
930
+ return thread;
931
+ }
932
+ const existingComment = thread.comments.find(
933
+ (comment) => comment.id === commentId
934
+ );
935
+ if (existingComment === void 0) {
936
+ return thread;
937
+ }
938
+ if (existingComment.deletedAt !== void 0) {
939
+ return thread;
940
+ }
941
+ const updatedComments = thread.comments.map(
942
+ (comment) => comment.id === commentId ? {
943
+ ...comment,
944
+ reactions: comment.reactions.map(
945
+ (reaction) => reaction.emoji === emoji ? {
946
+ ...reaction,
947
+ users: reaction.users.filter((user) => user.id !== userId)
948
+ } : reaction
949
+ ).filter((reaction) => reaction.users.length > 0)
950
+ // Remove reactions with no users left
951
+ } : comment
952
+ );
953
+ return {
954
+ ...thread,
955
+ updatedAt: new Date(
956
+ Math.max(removedAt.getTime(), _optionalChain([thread, 'access', _14 => _14.updatedAt, 'optionalAccess', _15 => _15.getTime, 'call', _16 => _16()]) || 0)
957
+ ),
958
+ comments: updatedComments
959
+ };
960
+ }
961
+ function upsertReaction(reactions, reaction) {
962
+ const existingReaction = reactions.find(
963
+ (existingReaction2) => existingReaction2.emoji === reaction.emoji
964
+ );
965
+ if (existingReaction === void 0) {
966
+ return [
967
+ ...reactions,
968
+ {
969
+ emoji: reaction.emoji,
970
+ createdAt: reaction.createdAt,
971
+ users: [{ id: reaction.userId }]
972
+ }
973
+ ];
974
+ }
975
+ if (existingReaction.users.some((user) => user.id === reaction.userId) === false) {
976
+ return reactions.map(
977
+ (existingReaction2) => existingReaction2.emoji === reaction.emoji ? {
978
+ ...existingReaction2,
979
+ users: [...existingReaction2.users, { id: reaction.userId }]
980
+ } : existingReaction2
981
+ );
982
+ }
983
+ return reactions;
984
+ }
985
+
986
+ // src/liveblocks.tsx
323
987
  var ClientContext = _react.createContext.call(void 0, null);
324
988
  function missingUserError(userId) {
325
989
  return new Error(`resolveUsers didn't return anything for user '${userId}'`);
@@ -329,6 +993,7 @@ function missingRoomInfoError(roomId) {
329
993
  `resolveRoomsInfo didn't return anything for room '${roomId}'`
330
994
  );
331
995
  }
996
+ var _umbrellaStores = /* @__PURE__ */ new WeakMap();
332
997
  var _extras = /* @__PURE__ */ new WeakMap();
333
998
  var _bundles = /* @__PURE__ */ new WeakMap();
334
999
  var POLLING_INTERVAL = 60 * 1e3;
@@ -348,32 +1013,24 @@ function selectorFor_useInboxNotifications(state) {
348
1013
  };
349
1014
  }
350
1015
  return {
351
- inboxNotifications: selectedInboxNotifications(state),
1016
+ inboxNotifications: selectInboxNotifications(state),
352
1017
  isLoading: false
353
1018
  };
354
1019
  }
355
- function selectorFor_useUserThreads(state) {
356
- const query = state.queries[USER_THREADS_QUERY];
357
- if (query === void 0 || query.isLoading) {
358
- return {
359
- isLoading: true
360
- };
361
- }
362
- if (query.error !== void 0) {
363
- return {
364
- threads: [],
365
- error: query.error,
366
- isLoading: false
367
- };
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));
368
1028
  }
369
- return {
370
- threads: selectedUserThreads(state),
371
- isLoading: false
372
- };
1029
+ return threads.sort(byMostRecentlyUpdated);
373
1030
  }
374
1031
  function selectUnreadInboxNotificationsCount(state) {
375
1032
  let count = 0;
376
- for (const notification of selectedInboxNotifications(state)) {
1033
+ for (const notification of selectInboxNotifications(state)) {
377
1034
  if (notification.readAt === null || notification.readAt < notification.notifiedAt) {
378
1035
  count++;
379
1036
  }
@@ -399,7 +1056,7 @@ function selectorFor_useUnreadInboxNotificationsCount(state) {
399
1056
  };
400
1057
  }
401
1058
  function selectorFor_useUser(state, userId) {
402
- if (state === void 0 || _optionalChain([state, 'optionalAccess', _2 => _2.isLoading])) {
1059
+ if (state === void 0 || _optionalChain([state, 'optionalAccess', _17 => _17.isLoading])) {
403
1060
  return _nullishCoalesce(state, () => ( { isLoading: true }));
404
1061
  }
405
1062
  if (state.error) {
@@ -417,7 +1074,7 @@ function selectorFor_useUser(state, userId) {
417
1074
  };
418
1075
  }
419
1076
  function selectorFor_useRoomInfo(state, roomId) {
420
- if (state === void 0 || _optionalChain([state, 'optionalAccess', _3 => _3.isLoading])) {
1077
+ if (state === void 0 || _optionalChain([state, 'optionalAccess', _18 => _18.isLoading])) {
421
1078
  return _nullishCoalesce(state, () => ( { isLoading: true }));
422
1079
  }
423
1080
  if (state.error) {
@@ -434,6 +1091,13 @@ function selectorFor_useRoomInfo(state, roomId) {
434
1091
  info: state.data
435
1092
  };
436
1093
  }
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()
1099
+ );
1100
+ }
437
1101
  function getOrCreateContextBundle(client) {
438
1102
  let bundle = _bundles.get(client);
439
1103
  if (!bundle) {
@@ -442,6 +1106,14 @@ function getOrCreateContextBundle(client) {
442
1106
  }
443
1107
  return bundle;
444
1108
  }
1109
+ function getUmbrellaStoreForClient(client) {
1110
+ let store = _umbrellaStores.get(client);
1111
+ if (!store) {
1112
+ store = new UmbrellaStore();
1113
+ _umbrellaStores.set(client, store);
1114
+ }
1115
+ return store;
1116
+ }
445
1117
  function getExtrasForClient(client) {
446
1118
  let extras = _extras.get(client);
447
1119
  if (!extras) {
@@ -451,8 +1123,7 @@ function getExtrasForClient(client) {
451
1123
  return extras;
452
1124
  }
453
1125
  function makeExtrasForClient(client) {
454
- const internals = client[_core.kInternal];
455
- const store = internals.cacheStore;
1126
+ const store = getUmbrellaStoreForClient(client);
456
1127
  let lastRequestedAt;
457
1128
  async function fetchInboxNotifications() {
458
1129
  if (lastRequestedAt === void 0) {
@@ -491,9 +1162,7 @@ function makeExtrasForClient(client) {
491
1162
  }
492
1163
  });
493
1164
  const waitUntilInboxNotificationsLoaded = _core.memoizeOnSuccess.call(void 0, async () => {
494
- store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {
495
- isLoading: true
496
- });
1165
+ store.setQueryLoading(INBOX_NOTIFICATIONS_QUERY);
497
1166
  try {
498
1167
  await autoRetry(
499
1168
  () => fetchInboxNotifications(),
@@ -501,10 +1170,7 @@ function makeExtrasForClient(client) {
501
1170
  [5e3, 5e3, 1e4, 15e3]
502
1171
  );
503
1172
  } catch (err) {
504
- store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {
505
- isLoading: false,
506
- error: err
507
- });
1173
+ store.setQueryError(INBOX_NOTIFICATIONS_QUERY, err);
508
1174
  throw err;
509
1175
  }
510
1176
  });
@@ -530,87 +1196,94 @@ function makeExtrasForClient(client) {
530
1196
  };
531
1197
  }, []);
532
1198
  }
533
- let userThreadsPollerSubscribers = 0;
534
- const userThreadsPoller = _core.makePoller.call(void 0, async () => {
1199
+ const userThreadsPoller = _core.makePoller.call(void 0, refreshUserThreads);
1200
+ let isFetchingUserThreadsUpdates = false;
1201
+ async function refreshUserThreads() {
1202
+ const since = userThreadslastRequestedAt;
1203
+ if (since === void 0 || isFetchingUserThreadsUpdates) {
1204
+ return;
1205
+ }
535
1206
  try {
536
- await waitUntilUserThreadsLoaded();
537
- await fetchUserThreads();
1207
+ isFetchingUserThreadsUpdates = true;
1208
+ const updates = await client[_core.kInternal].getThreadsSince({
1209
+ since
1210
+ });
1211
+ isFetchingUserThreadsUpdates = false;
1212
+ store.updateThreadsAndNotifications(
1213
+ updates.threads.updated,
1214
+ [],
1215
+ updates.threads.deleted,
1216
+ [],
1217
+ USER_THREADS_QUERY
1218
+ );
1219
+ userThreadslastRequestedAt = updates.requestedAt;
538
1220
  } catch (err) {
539
- console.warn(`Polling new user threads failed: ${String(err)}`);
1221
+ isFetchingUserThreadsUpdates = false;
1222
+ return;
540
1223
  }
541
- });
542
- let userThreadslastRequestedAt;
543
- function loadUserThreads() {
544
- void waitUntilUserThreadsLoaded().catch(() => {
545
- });
546
1224
  }
547
- const waitUntilUserThreadsLoaded = _core.memoizeOnSuccess.call(void 0, async () => {
548
- store.setQueryState(USER_THREADS_QUERY, {
549
- isLoading: true
550
- });
1225
+ const userThreadsSubscribersByQuery = /* @__PURE__ */ new Map();
1226
+ const userThreadsRequestsByQuery = /* @__PURE__ */ new Map();
1227
+ function incrementUserThreadsQuerySubscribers(queryKey) {
1228
+ const subscribers = _nullishCoalesce(userThreadsSubscribersByQuery.get(queryKey), () => ( 0));
1229
+ userThreadsSubscribersByQuery.set(queryKey, subscribers + 1);
1230
+ userThreadsPoller.start(POLLING_INTERVAL);
1231
+ return () => {
1232
+ const subscribers2 = userThreadsSubscribersByQuery.get(queryKey);
1233
+ if (subscribers2 === void 0 || subscribers2 <= 0) {
1234
+ console.warn(
1235
+ `Internal unexpected behavior. Cannot decrease subscriber count for query "${queryKey}"`
1236
+ );
1237
+ return;
1238
+ }
1239
+ userThreadsSubscribersByQuery.set(queryKey, subscribers2 - 1);
1240
+ let totalSubscribers = 0;
1241
+ for (const subscribers3 of userThreadsSubscribersByQuery.values()) {
1242
+ totalSubscribers += subscribers3;
1243
+ }
1244
+ if (totalSubscribers <= 0) {
1245
+ userThreadsPoller.stop();
1246
+ }
1247
+ };
1248
+ }
1249
+ let userThreadslastRequestedAt;
1250
+ async function getUserThreads(queryKey, options, { retryCount } = { retryCount: 0 }) {
1251
+ const existingRequest = userThreadsRequestsByQuery.get(queryKey);
1252
+ if (existingRequest !== void 0) return existingRequest;
1253
+ const request = client[_core.kInternal].getThreads(options);
1254
+ userThreadsRequestsByQuery.set(queryKey, request);
1255
+ store.setQueryLoading(queryKey);
551
1256
  try {
552
- await autoRetry(() => fetchUserThreads(), 5, [5e3, 5e3, 1e4, 15e3]);
553
- } catch (err) {
554
- store.setQueryState(USER_THREADS_QUERY, {
555
- isLoading: false,
556
- error: err
557
- });
558
- throw err;
559
- }
560
- });
561
- async function fetchUserThreads() {
562
- if (userThreadslastRequestedAt === void 0) {
563
- const result = await client[_core.kInternal].getThreads();
1257
+ const result = await request;
564
1258
  store.updateThreadsAndNotifications(
565
1259
  result.threads,
566
1260
  result.inboxNotifications,
567
1261
  [],
568
1262
  [],
569
- USER_THREADS_QUERY
570
- );
571
- userThreadslastRequestedAt = result.requestedAt;
572
- } else {
573
- const result = await client[_core.kInternal].getThreadsSince({
574
- since: userThreadslastRequestedAt
575
- });
576
- store.updateThreadsAndNotifications(
577
- result.threads.updated,
578
- result.inboxNotifications.updated,
579
- result.threads.deleted,
580
- result.inboxNotifications.deleted,
581
- USER_THREADS_QUERY
1263
+ queryKey
582
1264
  );
583
- if (userThreadslastRequestedAt < result.requestedAt) {
1265
+ if (userThreadslastRequestedAt === void 0 || userThreadslastRequestedAt < result.requestedAt) {
584
1266
  userThreadslastRequestedAt = result.requestedAt;
585
1267
  }
586
- }
587
- }
588
- function useEnableUserThreadsPolling() {
589
- _react.useEffect.call(void 0, () => {
590
- userThreadsPollerSubscribers++;
591
1268
  userThreadsPoller.start(POLLING_INTERVAL);
592
- return () => {
593
- if (userThreadsPollerSubscribers <= 0) {
594
- console.warn(
595
- `Internal unexpected behavior. Cannot decrease subscriber count for query "${USER_THREADS_QUERY}"`
596
- );
597
- return;
598
- }
599
- userThreadsPollerSubscribers--;
600
- if (userThreadsPollerSubscribers <= 0) {
601
- userThreadsPoller.stop();
602
- }
603
- };
604
- }, []);
1269
+ } catch (err) {
1270
+ userThreadsRequestsByQuery.delete(queryKey);
1271
+ retryError(() => {
1272
+ void getUserThreads(queryKey, options, {
1273
+ retryCount: retryCount + 1
1274
+ });
1275
+ }, retryCount);
1276
+ store.setQueryError(queryKey, err);
1277
+ }
1278
+ return;
605
1279
  }
606
1280
  return {
607
1281
  store,
608
1282
  useEnableInboxNotificationsPolling,
609
1283
  waitUntilInboxNotificationsLoaded,
610
1284
  loadInboxNotifications,
611
- useEnableUserThreadsPolling,
612
- waitUntilUserThreadsLoaded,
613
- loadUserThreads
1285
+ incrementUserThreadsQuerySubscribers,
1286
+ getUserThreads
614
1287
  };
615
1288
  }
616
1289
  function makeLiveblocksContextBundle(client) {
@@ -633,7 +1306,7 @@ function makeLiveblocksContextBundle(client) {
633
1306
  useDeleteInboxNotification: useDeleteInboxNotification2,
634
1307
  useDeleteAllInboxNotifications: useDeleteAllInboxNotifications2,
635
1308
  useInboxNotificationThread: useInboxNotificationThread2,
636
- useUserThreads_experimental: () => useUserThreads_withClient(client),
1309
+ useUserThreads_experimental,
637
1310
  ...shared.classic,
638
1311
  suspense: {
639
1312
  LiveblocksProvider: LiveblocksProvider2,
@@ -644,34 +1317,12 @@ function makeLiveblocksContextBundle(client) {
644
1317
  useDeleteInboxNotification: useDeleteInboxNotification2,
645
1318
  useDeleteAllInboxNotifications: useDeleteAllInboxNotifications2,
646
1319
  useInboxNotificationThread: useInboxNotificationThread2,
647
- useUserThreads_experimental: () => useUserThreadsSuspense_withClient(client),
1320
+ useUserThreads_experimental: useUserThreadsSuspense_experimental,
648
1321
  ...shared.suspense
649
1322
  }
650
1323
  };
651
1324
  return bundle;
652
1325
  }
653
- function useUserThreads_withClient(client) {
654
- const { loadUserThreads, store, useEnableUserThreadsPolling } = getExtrasForClient(client);
655
- _react.useEffect.call(void 0, () => {
656
- loadUserThreads();
657
- }, [loadUserThreads]);
658
- useEnableUserThreadsPolling();
659
- return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
660
- store.subscribe,
661
- store.get,
662
- store.get,
663
- selectorFor_useUserThreads,
664
- _core.shallow
665
- );
666
- }
667
- function useUserThreadsSuspense_withClient(client) {
668
- const { waitUntilUserThreadsLoaded } = getExtrasForClient(client);
669
- use(waitUntilUserThreadsLoaded());
670
- const result = useUserThreads_withClient(client);
671
- _core.assert.call(void 0, !result.error, "Did not expect error");
672
- _core.assert.call(void 0, !result.isLoading, "Did not expect loading");
673
- return result;
674
- }
675
1326
  function useInboxNotifications_withClient(client) {
676
1327
  const { loadInboxNotifications, store, useEnableInboxNotificationsPolling } = getExtrasForClient(client);
677
1328
  _react.useEffect.call(void 0, () => {
@@ -720,48 +1371,22 @@ function useMarkInboxNotificationAsRead_withClient(client) {
720
1371
  return _react.useCallback.call(void 0,
721
1372
  (inboxNotificationId) => {
722
1373
  const { store } = getExtrasForClient(client);
723
- const optimisticUpdateId = _core.nanoid.call(void 0, );
724
1374
  const readAt = /* @__PURE__ */ new Date();
725
- store.pushOptimisticUpdate({
1375
+ const optimisticUpdateId = store.addOptimisticUpdate({
726
1376
  type: "mark-inbox-notification-as-read",
727
- id: optimisticUpdateId,
728
1377
  inboxNotificationId,
729
1378
  readAt
730
1379
  });
731
1380
  client.markInboxNotificationAsRead(inboxNotificationId).then(
732
1381
  () => {
733
- store.set((state) => {
734
- const existingNotification = state.inboxNotifications[inboxNotificationId];
735
- if (existingNotification === void 0) {
736
- return {
737
- ...state,
738
- optimisticUpdates: state.optimisticUpdates.filter(
739
- (update) => update.id !== optimisticUpdateId
740
- )
741
- };
742
- }
743
- return {
744
- ...state,
745
- inboxNotifications: {
746
- ...state.inboxNotifications,
747
- [inboxNotificationId]: {
748
- ...existingNotification,
749
- readAt
750
- }
751
- },
752
- optimisticUpdates: state.optimisticUpdates.filter(
753
- (update) => update.id !== optimisticUpdateId
754
- )
755
- };
756
- });
1382
+ store.updateInboxNotification(
1383
+ inboxNotificationId,
1384
+ optimisticUpdateId,
1385
+ (inboxNotification) => ({ ...inboxNotification, readAt })
1386
+ );
757
1387
  },
758
1388
  () => {
759
- store.set((state) => ({
760
- ...state,
761
- optimisticUpdates: state.optimisticUpdates.filter(
762
- (update) => update.id !== optimisticUpdateId
763
- )
764
- }));
1389
+ store.removeOptimisticUpdate(optimisticUpdateId);
765
1390
  }
766
1391
  );
767
1392
  },
@@ -771,37 +1396,20 @@ function useMarkInboxNotificationAsRead_withClient(client) {
771
1396
  function useMarkAllInboxNotificationsAsRead_withClient(client) {
772
1397
  return _react.useCallback.call(void 0, () => {
773
1398
  const { store } = getExtrasForClient(client);
774
- const optimisticUpdateId = _core.nanoid.call(void 0, );
775
1399
  const readAt = /* @__PURE__ */ new Date();
776
- store.pushOptimisticUpdate({
1400
+ const optimisticUpdateId = store.addOptimisticUpdate({
777
1401
  type: "mark-all-inbox-notifications-as-read",
778
- id: optimisticUpdateId,
779
1402
  readAt
780
1403
  });
781
1404
  client.markAllInboxNotificationsAsRead().then(
782
1405
  () => {
783
- store.set((state) => ({
784
- ...state,
785
- inboxNotifications: Object.fromEntries(
786
- Array.from(Object.entries(state.inboxNotifications)).map(
787
- ([id, inboxNotification]) => [
788
- id,
789
- { ...inboxNotification, readAt }
790
- ]
791
- )
792
- ),
793
- optimisticUpdates: state.optimisticUpdates.filter(
794
- (update) => update.id !== optimisticUpdateId
795
- )
796
- }));
1406
+ store.updateAllInboxNotifications(
1407
+ optimisticUpdateId,
1408
+ (inboxNotification) => ({ ...inboxNotification, readAt })
1409
+ );
797
1410
  },
798
1411
  () => {
799
- store.set((state) => ({
800
- ...state,
801
- optimisticUpdates: state.optimisticUpdates.filter(
802
- (update) => update.id !== optimisticUpdateId
803
- )
804
- }));
1412
+ store.removeOptimisticUpdate(optimisticUpdateId);
805
1413
  }
806
1414
  );
807
1415
  }, [client]);
@@ -810,43 +1418,21 @@ function useDeleteInboxNotification_withClient(client) {
810
1418
  return _react.useCallback.call(void 0,
811
1419
  (inboxNotificationId) => {
812
1420
  const { store } = getExtrasForClient(client);
813
- const optimisticUpdateId = _core.nanoid.call(void 0, );
814
1421
  const deletedAt = /* @__PURE__ */ new Date();
815
- store.pushOptimisticUpdate({
1422
+ const optimisticUpdateId = store.addOptimisticUpdate({
816
1423
  type: "delete-inbox-notification",
817
- id: optimisticUpdateId,
818
1424
  inboxNotificationId,
819
1425
  deletedAt
820
1426
  });
821
1427
  client.deleteInboxNotification(inboxNotificationId).then(
822
1428
  () => {
823
- store.set((state) => {
824
- const existingNotification = state.inboxNotifications[inboxNotificationId];
825
- if (existingNotification === void 0) {
826
- return {
827
- ...state,
828
- optimisticUpdates: state.optimisticUpdates.filter(
829
- (update) => update.id !== optimisticUpdateId
830
- )
831
- };
832
- }
833
- const { [inboxNotificationId]: _, ...inboxNotifications } = state.inboxNotifications;
834
- return {
835
- ...state,
836
- inboxNotifications,
837
- optimisticUpdates: state.optimisticUpdates.filter(
838
- (update) => update.id !== optimisticUpdateId
839
- )
840
- };
841
- });
1429
+ store.deleteInboxNotification(
1430
+ inboxNotificationId,
1431
+ optimisticUpdateId
1432
+ );
842
1433
  },
843
1434
  () => {
844
- store.set((state) => ({
845
- ...state,
846
- optimisticUpdates: state.optimisticUpdates.filter(
847
- (update) => update.id !== optimisticUpdateId
848
- )
849
- }));
1435
+ store.removeOptimisticUpdate(optimisticUpdateId);
850
1436
  }
851
1437
  );
852
1438
  },
@@ -856,30 +1442,17 @@ function useDeleteInboxNotification_withClient(client) {
856
1442
  function useDeleteAllInboxNotifications_withClient(client) {
857
1443
  return _react.useCallback.call(void 0, () => {
858
1444
  const { store } = getExtrasForClient(client);
859
- const optimisticUpdateId = _core.nanoid.call(void 0, );
860
1445
  const deletedAt = /* @__PURE__ */ new Date();
861
- store.pushOptimisticUpdate({
1446
+ const optimisticUpdateId = store.addOptimisticUpdate({
862
1447
  type: "delete-all-inbox-notifications",
863
- id: optimisticUpdateId,
864
1448
  deletedAt
865
1449
  });
866
1450
  client.deleteAllInboxNotifications().then(
867
1451
  () => {
868
- store.set((state) => ({
869
- ...state,
870
- inboxNotifications: {},
871
- optimisticUpdates: state.optimisticUpdates.filter(
872
- (update) => update.id !== optimisticUpdateId
873
- )
874
- }));
1452
+ store.deleteAllInboxNotifications(optimisticUpdateId);
875
1453
  },
876
1454
  () => {
877
- store.set((state) => ({
878
- ...state,
879
- optimisticUpdates: state.optimisticUpdates.filter(
880
- (update) => update.id !== optimisticUpdateId
881
- )
882
- }));
1455
+ store.removeOptimisticUpdate(optimisticUpdateId);
883
1456
  }
884
1457
  );
885
1458
  }, [client]);
@@ -1030,7 +1603,7 @@ function createSharedContext(client) {
1030
1603
  }
1031
1604
  function useEnsureNoLiveblocksProvider(options) {
1032
1605
  const existing = useClientOrNull();
1033
- if (!_optionalChain([options, 'optionalAccess', _4 => _4.allowNesting]) && existing !== null) {
1606
+ if (!_optionalChain([options, 'optionalAccess', _19 => _19.allowNesting]) && existing !== null) {
1034
1607
  throw new Error(
1035
1608
  "You cannot nest multiple LiveblocksProvider instances in the same React tree."
1036
1609
  );
@@ -1077,11 +1650,89 @@ function LiveblocksProvider(props) {
1077
1650
  function createLiveblocksContext(client) {
1078
1651
  return getOrCreateContextBundle(client);
1079
1652
  }
1080
- function useUserThreads_experimental() {
1081
- return useUserThreads_withClient(useClient());
1653
+ function useUserThreads_experimental(options = {
1654
+ query: {
1655
+ metadata: {}
1656
+ }
1657
+ }) {
1658
+ const queryKey = React.default.useMemo(
1659
+ () => makeUserThreadsQueryKey(options.query),
1660
+ [options]
1661
+ );
1662
+ const client = useClient();
1663
+ const { store, incrementUserThreadsQuerySubscribers, getUserThreads } = getExtrasForClient(client);
1664
+ _react.useEffect.call(void 0, () => {
1665
+ void getUserThreads(queryKey, options);
1666
+ return incrementUserThreadsQuerySubscribers(queryKey);
1667
+ }, [queryKey, incrementUserThreadsQuerySubscribers, getUserThreads, options]);
1668
+ const selector = _react.useCallback.call(void 0,
1669
+ (state) => {
1670
+ const query = state.queries[queryKey];
1671
+ if (query === void 0 || query.isLoading) {
1672
+ return {
1673
+ isLoading: true
1674
+ };
1675
+ }
1676
+ if (query.error !== void 0) {
1677
+ return {
1678
+ threads: [],
1679
+ error: query.error,
1680
+ isLoading: false
1681
+ };
1682
+ }
1683
+ return {
1684
+ threads: selectUserThreads(state, options),
1685
+ isLoading: false
1686
+ };
1687
+ },
1688
+ [queryKey, options]
1689
+ );
1690
+ return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
1691
+ store.subscribe,
1692
+ store.get,
1693
+ store.get,
1694
+ selector,
1695
+ _core.shallow
1696
+ );
1082
1697
  }
1083
- function useUserThreadsSuspense_experimental() {
1084
- return useUserThreadsSuspense_withClient(useClient());
1698
+ function useUserThreadsSuspense_experimental(options = {
1699
+ query: {
1700
+ metadata: {}
1701
+ }
1702
+ }) {
1703
+ const queryKey = React.default.useMemo(
1704
+ () => makeUserThreadsQueryKey(options.query),
1705
+ [options]
1706
+ );
1707
+ const client = useClient();
1708
+ const { store, getUserThreads } = getExtrasForClient(client);
1709
+ React.default.useEffect(() => {
1710
+ const { incrementUserThreadsQuerySubscribers } = getExtrasForClient(client);
1711
+ return incrementUserThreadsQuerySubscribers(queryKey);
1712
+ }, [client, queryKey]);
1713
+ const query = store.get().queries[queryKey];
1714
+ if (query === void 0 || query.isLoading) {
1715
+ throw getUserThreads(queryKey, options);
1716
+ }
1717
+ if (query.error) {
1718
+ throw query.error;
1719
+ }
1720
+ const selector = _react.useCallback.call(void 0,
1721
+ (state) => {
1722
+ return {
1723
+ threads: selectUserThreads(state, options),
1724
+ isLoading: false
1725
+ };
1726
+ },
1727
+ [options]
1728
+ );
1729
+ return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
1730
+ store.subscribe,
1731
+ store.get,
1732
+ store.get,
1733
+ selector,
1734
+ _core.shallow
1735
+ );
1085
1736
  }
1086
1737
  function useInboxNotifications() {
1087
1738
  return useInboxNotifications_withClient(useClient());
@@ -1132,6 +1783,7 @@ var _useUser = useUser;
1132
1783
  var _useUserSuspense = useUserSuspense;
1133
1784
  var _useUserThreads_experimental = useUserThreads_experimental;
1134
1785
  var _useUserThreadsSuspense_experimental = useUserThreadsSuspense_experimental;
1786
+ var makeUserThreadsQueryKey = (options) => `${USER_THREADS_QUERY}:${_core.stringify.call(void 0, options)}`;
1135
1787
 
1136
1788
  // src/use-scroll-to-comment-on-load-effect.ts
1137
1789
 
@@ -1196,6 +1848,22 @@ function alwaysNull() {
1196
1848
  function selectorFor_useOthersConnectionIds(others) {
1197
1849
  return others.map((user) => user.connectionId);
1198
1850
  }
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
+ function selectNotificationSettings(roomId, state) {
1864
+ const { notificationSettings } = applyOptimisticUpdates(state);
1865
+ return _core.nn.call(void 0, notificationSettings[roomId]);
1866
+ }
1199
1867
  function makeMutationContext(room) {
1200
1868
  const cannotUseUntil = "This mutation cannot be used until";
1201
1869
  const needsPresence = `${cannotUseUntil} connected to the Liveblocks room`;
@@ -1235,7 +1903,7 @@ function getCurrentUserId(room) {
1235
1903
  }
1236
1904
  function handleApiError(err) {
1237
1905
  const message = `Request failed with status ${err.status}: ${err.message}`;
1238
- if (_optionalChain([err, 'access', _5 => _5.details, 'optionalAccess', _6 => _6.error]) === "FORBIDDEN") {
1906
+ if (_optionalChain([err, 'access', _20 => _20.details, 'optionalAccess', _21 => _21.error]) === "FORBIDDEN") {
1239
1907
  const detailedMessage = [message, err.details.suggestion, err.details.docs].filter(Boolean).join("\n");
1240
1908
  _core.console.error(detailedMessage);
1241
1909
  }
@@ -1260,7 +1928,7 @@ function getExtrasForClient2(client) {
1260
1928
  return extras;
1261
1929
  }
1262
1930
  function makeExtrasForClient2(client) {
1263
- const store = client[_core.kInternal].cacheStore;
1931
+ const store = getUmbrellaStoreForClient(client);
1264
1932
  const DEFAULT_DEDUPING_INTERVAL = 2e3;
1265
1933
  const lastRequestedAtByRoom = /* @__PURE__ */ new Map();
1266
1934
  const requestsByQuery = /* @__PURE__ */ new Map();
@@ -1329,9 +1997,7 @@ function makeExtrasForClient2(client) {
1329
1997
  if (existingRequest !== void 0) return existingRequest;
1330
1998
  const request = room[_core.kInternal].listTextVersions();
1331
1999
  requestsByQuery.set(queryKey, request);
1332
- store.setQueryState(queryKey, {
1333
- isLoading: true
1334
- });
2000
+ store.setQueryLoading(queryKey);
1335
2001
  try {
1336
2002
  const result = await request;
1337
2003
  const data = await result.json();
@@ -1350,10 +2016,7 @@ function makeExtrasForClient2(client) {
1350
2016
  retryCount: retryCount + 1
1351
2017
  });
1352
2018
  }, retryCount);
1353
- store.setQueryState(queryKey, {
1354
- isLoading: false,
1355
- error: err
1356
- });
2019
+ store.setQueryError(queryKey, err);
1357
2020
  }
1358
2021
  return;
1359
2022
  }
@@ -1362,9 +2025,7 @@ function makeExtrasForClient2(client) {
1362
2025
  if (existingRequest !== void 0) return existingRequest;
1363
2026
  const request = room.getThreads(options);
1364
2027
  requestsByQuery.set(queryKey, request);
1365
- store.setQueryState(queryKey, {
1366
- isLoading: true
1367
- });
2028
+ store.setQueryLoading(queryKey);
1368
2029
  try {
1369
2030
  const result = await request;
1370
2031
  store.updateThreadsAndNotifications(
@@ -1387,10 +2048,7 @@ function makeExtrasForClient2(client) {
1387
2048
  retryCount: retryCount + 1
1388
2049
  });
1389
2050
  }, retryCount);
1390
- store.setQueryState(queryKey, {
1391
- isLoading: false,
1392
- error: err
1393
- });
2051
+ store.setQueryError(queryKey, err);
1394
2052
  }
1395
2053
  return;
1396
2054
  }
@@ -1400,9 +2058,7 @@ function makeExtrasForClient2(client) {
1400
2058
  try {
1401
2059
  const request = room.getNotificationSettings();
1402
2060
  requestsByQuery.set(queryKey, request);
1403
- store.setQueryState(queryKey, {
1404
- isLoading: true
1405
- });
2061
+ store.setQueryLoading(queryKey);
1406
2062
  const settings = await request;
1407
2063
  store.updateRoomInboxNotificationSettings(room.id, settings, queryKey);
1408
2064
  } catch (err) {
@@ -1412,21 +2068,13 @@ function makeExtrasForClient2(client) {
1412
2068
  retryCount: retryCount + 1
1413
2069
  });
1414
2070
  }, retryCount);
1415
- store.setQueryState(queryKey, {
1416
- isLoading: false,
1417
- error: err
1418
- });
2071
+ store.setQueryError(queryKey, err);
1419
2072
  }
1420
2073
  return;
1421
2074
  }
1422
2075
  const commentsErrorEventSource = _core.makeEventSource.call(void 0, );
1423
2076
  function onMutationFailure(innerError, optimisticUpdateId, createPublicError) {
1424
- store.set((state) => ({
1425
- ...state,
1426
- optimisticUpdates: state.optimisticUpdates.filter(
1427
- (update) => update.id !== optimisticUpdateId
1428
- )
1429
- }));
2077
+ store.removeOptimisticUpdate(optimisticUpdateId);
1430
2078
  if (innerError instanceof _core.CommentsApiError) {
1431
2079
  const error = handleApiError(innerError);
1432
2080
  commentsErrorEventSource.notify(createPublicError(error));
@@ -1589,7 +2237,7 @@ function RoomProviderInner(props) {
1589
2237
  "RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required"
1590
2238
  );
1591
2239
  }
1592
- if (typeof roomId !== "string") {
2240
+ if (!isString(roomId)) {
1593
2241
  throw new Error("RoomProvider id property should be a string.");
1594
2242
  }
1595
2243
  const majorReactVersion = parseInt(React4.version) || 1;
@@ -1620,12 +2268,12 @@ function RoomProviderInner(props) {
1620
2268
  const { store } = getExtrasForClient2(client);
1621
2269
  async function handleCommentEvent(message) {
1622
2270
  if (message.type === _core.ServerMsgCode.THREAD_DELETED) {
1623
- store.deleteThread(message.threadId);
2271
+ store.deleteThread(message.threadId, null);
1624
2272
  return;
1625
2273
  }
1626
2274
  const info = await room.getThread(message.threadId);
1627
2275
  if (!info.thread) {
1628
- store.deleteThread(message.threadId);
2276
+ store.deleteThread(message.threadId, null);
1629
2277
  return;
1630
2278
  }
1631
2279
  const { thread, inboxNotification } = info;
@@ -1697,7 +2345,7 @@ function useStatus() {
1697
2345
  return useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot);
1698
2346
  }
1699
2347
  function useStorageStatus(options) {
1700
- const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _7 => _7.smooth]), () => ( false)));
2348
+ const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _22 => _22.smooth]), () => ( false)));
1701
2349
  if (smooth) {
1702
2350
  return useStorageStatusSmooth();
1703
2351
  } else {
@@ -1974,7 +2622,7 @@ function useThreads(options = {
1974
2622
  };
1975
2623
  }
1976
2624
  return {
1977
- threads: selectedThreads(room.id, state2, options),
2625
+ threads: selectRoomThreads(room.id, state2, options),
1978
2626
  isLoading: false,
1979
2627
  error: query.error
1980
2628
  };
@@ -2029,26 +2677,15 @@ function useCreateThread() {
2029
2677
  comments: [newComment],
2030
2678
  resolved: false
2031
2679
  };
2032
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2033
2680
  const { store, onMutationFailure } = getExtrasForClient2(client);
2034
- store.pushOptimisticUpdate({
2681
+ const optimisticUpdateId = store.addOptimisticUpdate({
2035
2682
  type: "create-thread",
2036
2683
  thread: newThread,
2037
- id: optimisticUpdateId,
2038
2684
  roomId: room.id
2039
2685
  });
2040
2686
  room.createThread({ threadId, commentId, body, metadata }).then(
2041
2687
  (thread) => {
2042
- store.set((state) => ({
2043
- ...state,
2044
- threads: {
2045
- ...state.threads,
2046
- [threadId]: thread
2047
- },
2048
- optimisticUpdates: state.optimisticUpdates.filter(
2049
- (update) => update.id !== optimisticUpdateId
2050
- )
2051
- }));
2688
+ store.createThread(optimisticUpdateId, thread);
2052
2689
  },
2053
2690
  (err) => onMutationFailure(
2054
2691
  err,
@@ -2072,42 +2709,21 @@ function useDeleteThread() {
2072
2709
  const room = useRoom();
2073
2710
  return React4.useCallback(
2074
2711
  (threadId) => {
2075
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2076
2712
  const { store, onMutationFailure } = getExtrasForClient2(client);
2077
2713
  const thread = store.get().threads[threadId];
2078
2714
  const userId = getCurrentUserId(room);
2079
- if (_optionalChain([thread, 'optionalAccess', _8 => _8.comments, 'optionalAccess', _9 => _9[0], 'optionalAccess', _10 => _10.userId]) !== userId) {
2715
+ if (_optionalChain([thread, 'optionalAccess', _23 => _23.comments, 'optionalAccess', _24 => _24[0], 'optionalAccess', _25 => _25.userId]) !== userId) {
2080
2716
  throw new Error("Only the thread creator can delete the thread");
2081
2717
  }
2082
- store.pushOptimisticUpdate({
2718
+ const optimisticUpdateId = store.addOptimisticUpdate({
2083
2719
  type: "delete-thread",
2084
- id: optimisticUpdateId,
2085
2720
  roomId: room.id,
2086
2721
  threadId,
2087
2722
  deletedAt: /* @__PURE__ */ new Date()
2088
2723
  });
2089
2724
  room.deleteThread(threadId).then(
2090
2725
  () => {
2091
- store.set((state) => {
2092
- const existingThread = state.threads[threadId];
2093
- if (existingThread === void 0) {
2094
- return state;
2095
- }
2096
- return {
2097
- ...state,
2098
- threads: {
2099
- ...state.threads,
2100
- [threadId]: {
2101
- ...existingThread,
2102
- updatedAt: /* @__PURE__ */ new Date(),
2103
- deletedAt: /* @__PURE__ */ new Date()
2104
- }
2105
- },
2106
- optimisticUpdates: state.optimisticUpdates.filter(
2107
- (update) => update.id !== optimisticUpdateId
2108
- )
2109
- };
2110
- });
2726
+ store.deleteThread(threadId, optimisticUpdateId);
2111
2727
  },
2112
2728
  (err) => onMutationFailure(
2113
2729
  err,
@@ -2130,53 +2746,23 @@ function useEditThreadMetadata() {
2130
2746
  const threadId = options.threadId;
2131
2747
  const metadata = options.metadata;
2132
2748
  const updatedAt = /* @__PURE__ */ new Date();
2133
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2134
2749
  const { store, onMutationFailure } = getExtrasForClient2(client);
2135
- store.pushOptimisticUpdate({
2750
+ const optimisticUpdateId = store.addOptimisticUpdate({
2136
2751
  type: "edit-thread-metadata",
2137
2752
  metadata,
2138
- id: optimisticUpdateId,
2139
2753
  threadId,
2140
2754
  updatedAt
2141
2755
  });
2142
- room.editThreadMetadata({ metadata, threadId }).then(
2143
- (metadata2) => {
2144
- store.set((state) => {
2145
- const existingThread = state.threads[threadId];
2146
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2147
- (update) => update.id !== optimisticUpdateId
2148
- );
2149
- if (existingThread === void 0) {
2150
- return {
2151
- ...state,
2152
- optimisticUpdates: updatedOptimisticUpdates
2153
- };
2154
- }
2155
- if (existingThread.deletedAt !== void 0) {
2156
- return {
2157
- ...state,
2158
- optimisticUpdates: updatedOptimisticUpdates
2159
- };
2160
- }
2161
- if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
2162
- return {
2163
- ...state,
2164
- optimisticUpdates: updatedOptimisticUpdates
2165
- };
2166
- }
2167
- return {
2168
- ...state,
2169
- threads: {
2170
- ...state.threads,
2171
- [threadId]: {
2172
- ...existingThread,
2173
- metadata: metadata2
2174
- }
2175
- },
2176
- optimisticUpdates: updatedOptimisticUpdates
2177
- };
2178
- });
2179
- },
2756
+ room.editThreadMetadata({ threadId, metadata }).then(
2757
+ (metadata2) => (
2758
+ // Replace the optimistic update by the real thing
2759
+ store.updateThread(
2760
+ threadId,
2761
+ optimisticUpdateId,
2762
+ (thread) => ({ ...thread, metadata: metadata2 }),
2763
+ updatedAt
2764
+ )
2765
+ ),
2180
2766
  (err) => onMutationFailure(
2181
2767
  err,
2182
2768
  optimisticUpdateId,
@@ -2208,50 +2794,14 @@ function useCreateComment() {
2208
2794
  body,
2209
2795
  reactions: []
2210
2796
  };
2211
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2212
2797
  const { store, onMutationFailure } = getExtrasForClient2(client);
2213
- store.pushOptimisticUpdate({
2798
+ const optimisticUpdateId = store.addOptimisticUpdate({
2214
2799
  type: "create-comment",
2215
- comment,
2216
- id: optimisticUpdateId
2800
+ comment
2217
2801
  });
2218
2802
  room.createComment({ threadId, commentId, body }).then(
2219
2803
  (newComment) => {
2220
- store.set((state) => {
2221
- const existingThread = state.threads[threadId];
2222
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2223
- (update) => update.id !== optimisticUpdateId
2224
- );
2225
- if (existingThread === void 0) {
2226
- return {
2227
- ...state,
2228
- optimisticUpdates: updatedOptimisticUpdates
2229
- };
2230
- }
2231
- const inboxNotification = Object.values(
2232
- state.inboxNotifications
2233
- ).find(
2234
- (notification) => notification.kind === "thread" && notification.threadId === threadId
2235
- );
2236
- const updatedInboxNotifications = inboxNotification !== void 0 ? {
2237
- ...state.inboxNotifications,
2238
- [inboxNotification.id]: {
2239
- ...inboxNotification,
2240
- notifiedAt: newComment.createdAt,
2241
- readAt: newComment.createdAt
2242
- }
2243
- } : state.inboxNotifications;
2244
- return {
2245
- ...state,
2246
- threads: {
2247
- ...state.threads,
2248
- [threadId]: _core.upsertComment.call(void 0, existingThread, newComment)
2249
- // Upsert the new comment into the thread comments list (if applicable)
2250
- },
2251
- inboxNotifications: updatedInboxNotifications,
2252
- optimisticUpdates: updatedOptimisticUpdates
2253
- };
2254
- });
2804
+ store.createComment(newComment, optimisticUpdateId);
2255
2805
  },
2256
2806
  (err) => onMutationFailure(
2257
2807
  err,
@@ -2275,7 +2825,6 @@ function useEditComment() {
2275
2825
  return React4.useCallback(
2276
2826
  ({ threadId, commentId, body }) => {
2277
2827
  const editedAt = /* @__PURE__ */ new Date();
2278
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2279
2828
  const { store, onMutationFailure } = getExtrasForClient2(client);
2280
2829
  const thread = store.get().threads[threadId];
2281
2830
  if (thread === void 0) {
@@ -2293,38 +2842,21 @@ function useEditComment() {
2293
2842
  );
2294
2843
  return;
2295
2844
  }
2296
- store.pushOptimisticUpdate({
2845
+ const optimisticUpdateId = store.addOptimisticUpdate({
2297
2846
  type: "edit-comment",
2298
2847
  comment: {
2299
2848
  ...comment,
2300
2849
  editedAt,
2301
2850
  body
2302
- },
2303
- id: optimisticUpdateId
2851
+ }
2304
2852
  });
2305
2853
  room.editComment({ threadId, commentId, body }).then(
2306
2854
  (editedComment) => {
2307
- store.set((state) => {
2308
- const existingThread = state.threads[threadId];
2309
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2310
- (update) => update.id !== optimisticUpdateId
2311
- );
2312
- if (existingThread === void 0) {
2313
- return {
2314
- ...state,
2315
- optimisticUpdates: updatedOptimisticUpdates
2316
- };
2317
- }
2318
- return {
2319
- ...state,
2320
- threads: {
2321
- ...state.threads,
2322
- [threadId]: _core.upsertComment.call(void 0, existingThread, editedComment)
2323
- // Upsert the edited comment into the thread comments list (if applicable)
2324
- },
2325
- optimisticUpdates: updatedOptimisticUpdates
2326
- };
2327
- });
2855
+ store.updateThread(
2856
+ threadId,
2857
+ optimisticUpdateId,
2858
+ (thread2) => upsertComment(thread2, editedComment)
2859
+ );
2328
2860
  },
2329
2861
  (err) => onMutationFailure(
2330
2862
  err,
@@ -2347,38 +2879,22 @@ function useDeleteComment() {
2347
2879
  return React4.useCallback(
2348
2880
  ({ threadId, commentId }) => {
2349
2881
  const deletedAt = /* @__PURE__ */ new Date();
2350
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2351
2882
  const { store, onMutationFailure } = getExtrasForClient2(client);
2352
- store.pushOptimisticUpdate({
2883
+ const optimisticUpdateId = store.addOptimisticUpdate({
2353
2884
  type: "delete-comment",
2354
2885
  threadId,
2355
2886
  commentId,
2356
2887
  deletedAt,
2357
- id: optimisticUpdateId,
2358
2888
  roomId: room.id
2359
2889
  });
2360
2890
  room.deleteComment({ threadId, commentId }).then(
2361
2891
  () => {
2362
- store.set((state) => {
2363
- const existingThread = state.threads[threadId];
2364
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2365
- (update) => update.id !== optimisticUpdateId
2366
- );
2367
- if (existingThread === void 0) {
2368
- return {
2369
- ...state,
2370
- optimisticUpdates: updatedOptimisticUpdates
2371
- };
2372
- }
2373
- return {
2374
- ...state,
2375
- threads: {
2376
- ...state.threads,
2377
- [threadId]: _core.deleteComment.call(void 0, existingThread, commentId, deletedAt)
2378
- },
2379
- optimisticUpdates: updatedOptimisticUpdates
2380
- };
2381
- });
2892
+ store.updateThread(
2893
+ threadId,
2894
+ optimisticUpdateId,
2895
+ (thread) => deleteComment(thread, commentId, deletedAt),
2896
+ deletedAt
2897
+ );
2382
2898
  },
2383
2899
  (err) => onMutationFailure(
2384
2900
  err,
@@ -2401,9 +2917,8 @@ function useAddReaction() {
2401
2917
  ({ threadId, commentId, emoji }) => {
2402
2918
  const createdAt = /* @__PURE__ */ new Date();
2403
2919
  const userId = getCurrentUserId(room);
2404
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2405
2920
  const { store, onMutationFailure } = getExtrasForClient2(client);
2406
- store.pushOptimisticUpdate({
2921
+ const optimisticUpdateId = store.addOptimisticUpdate({
2407
2922
  type: "add-reaction",
2408
2923
  threadId,
2409
2924
  commentId,
@@ -2411,35 +2926,16 @@ function useAddReaction() {
2411
2926
  emoji,
2412
2927
  userId,
2413
2928
  createdAt
2414
- },
2415
- id: optimisticUpdateId
2929
+ }
2416
2930
  });
2417
2931
  room.addReaction({ threadId, commentId, emoji }).then(
2418
2932
  (addedReaction) => {
2419
- store.set((state) => {
2420
- const existingThread = state.threads[threadId];
2421
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2422
- (update) => update.id !== optimisticUpdateId
2423
- );
2424
- if (existingThread === void 0) {
2425
- return {
2426
- ...state,
2427
- optimisticUpdates: updatedOptimisticUpdates
2428
- };
2429
- }
2430
- return {
2431
- ...state,
2432
- threads: {
2433
- ...state.threads,
2434
- [threadId]: _core.addReaction.call(void 0,
2435
- existingThread,
2436
- commentId,
2437
- addedReaction
2438
- )
2439
- },
2440
- optimisticUpdates: updatedOptimisticUpdates
2441
- };
2442
- });
2933
+ store.updateThread(
2934
+ threadId,
2935
+ optimisticUpdateId,
2936
+ (thread) => addReaction(thread, commentId, addedReaction),
2937
+ createdAt
2938
+ );
2443
2939
  },
2444
2940
  (err) => onMutationFailure(
2445
2941
  err,
@@ -2463,45 +2959,23 @@ function useRemoveReaction() {
2463
2959
  ({ threadId, commentId, emoji }) => {
2464
2960
  const userId = getCurrentUserId(room);
2465
2961
  const removedAt = /* @__PURE__ */ new Date();
2466
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2467
2962
  const { store, onMutationFailure } = getExtrasForClient2(client);
2468
- store.pushOptimisticUpdate({
2963
+ const optimisticUpdateId = store.addOptimisticUpdate({
2469
2964
  type: "remove-reaction",
2470
2965
  threadId,
2471
2966
  commentId,
2472
2967
  emoji,
2473
2968
  userId,
2474
- removedAt,
2475
- id: optimisticUpdateId
2969
+ removedAt
2476
2970
  });
2477
2971
  room.removeReaction({ threadId, commentId, emoji }).then(
2478
2972
  () => {
2479
- store.set((state) => {
2480
- const existingThread = state.threads[threadId];
2481
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2482
- (update) => update.id !== optimisticUpdateId
2483
- );
2484
- if (existingThread === void 0) {
2485
- return {
2486
- ...state,
2487
- optimisticUpdates: updatedOptimisticUpdates
2488
- };
2489
- }
2490
- return {
2491
- ...state,
2492
- threads: {
2493
- ...state.threads,
2494
- [threadId]: _core.removeReaction.call(void 0,
2495
- existingThread,
2496
- commentId,
2497
- emoji,
2498
- userId,
2499
- removedAt
2500
- )
2501
- },
2502
- optimisticUpdates: updatedOptimisticUpdates
2503
- };
2504
- });
2973
+ store.updateThread(
2974
+ threadId,
2975
+ optimisticUpdateId,
2976
+ (thread) => removeReaction(thread, commentId, emoji, userId, removedAt),
2977
+ removedAt
2978
+ );
2505
2979
  },
2506
2980
  (err) => onMutationFailure(
2507
2981
  err,
@@ -2530,29 +3004,19 @@ function useMarkThreadAsRead() {
2530
3004
  (inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
2531
3005
  );
2532
3006
  if (!inboxNotification) return;
2533
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2534
3007
  const now = /* @__PURE__ */ new Date();
2535
- store.pushOptimisticUpdate({
3008
+ const optimisticUpdateId = store.addOptimisticUpdate({
2536
3009
  type: "mark-inbox-notification-as-read",
2537
- id: optimisticUpdateId,
2538
3010
  inboxNotificationId: inboxNotification.id,
2539
3011
  readAt: now
2540
3012
  });
2541
3013
  room.markInboxNotificationAsRead(inboxNotification.id).then(
2542
3014
  () => {
2543
- store.set((state) => ({
2544
- ...state,
2545
- inboxNotifications: {
2546
- ...state.inboxNotifications,
2547
- [inboxNotification.id]: {
2548
- ...inboxNotification,
2549
- readAt: now
2550
- }
2551
- },
2552
- optimisticUpdates: state.optimisticUpdates.filter(
2553
- (update) => update.id !== optimisticUpdateId
2554
- )
2555
- }));
3015
+ store.updateInboxNotification(
3016
+ inboxNotification.id,
3017
+ optimisticUpdateId,
3018
+ (inboxNotification2) => ({ ...inboxNotification2, readAt: now })
3019
+ );
2556
3020
  },
2557
3021
  (err) => {
2558
3022
  onMutationFailure(
@@ -2574,52 +3038,21 @@ function useMarkThreadAsResolved() {
2574
3038
  const room = useRoom();
2575
3039
  return React4.useCallback(
2576
3040
  (threadId) => {
2577
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2578
3041
  const updatedAt = /* @__PURE__ */ new Date();
2579
3042
  const { store, onMutationFailure } = getExtrasForClient2(client);
2580
- store.pushOptimisticUpdate({
3043
+ const optimisticUpdateId = store.addOptimisticUpdate({
2581
3044
  type: "mark-thread-as-resolved",
2582
- id: optimisticUpdateId,
2583
3045
  threadId,
2584
3046
  updatedAt
2585
3047
  });
2586
3048
  room.markThreadAsResolved(threadId).then(
2587
3049
  () => {
2588
- store.set((state) => {
2589
- const existingThread = state.threads[threadId];
2590
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2591
- (update) => update.id !== optimisticUpdateId
2592
- );
2593
- if (existingThread === void 0) {
2594
- return {
2595
- ...state,
2596
- optimisticUpdates: updatedOptimisticUpdates
2597
- };
2598
- }
2599
- if (existingThread.deletedAt !== void 0) {
2600
- return {
2601
- ...state,
2602
- optimisticUpdates: updatedOptimisticUpdates
2603
- };
2604
- }
2605
- if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
2606
- return {
2607
- ...state,
2608
- optimisticUpdates: updatedOptimisticUpdates
2609
- };
2610
- }
2611
- return {
2612
- ...state,
2613
- threads: {
2614
- ...state.threads,
2615
- [threadId]: {
2616
- ...existingThread,
2617
- resolved: true
2618
- }
2619
- },
2620
- optimisticUpdates: updatedOptimisticUpdates
2621
- };
2622
- });
3050
+ store.updateThread(
3051
+ threadId,
3052
+ optimisticUpdateId,
3053
+ (thread) => ({ ...thread, resolved: true }),
3054
+ updatedAt
3055
+ );
2623
3056
  },
2624
3057
  (err) => onMutationFailure(
2625
3058
  err,
@@ -2639,52 +3072,21 @@ function useMarkThreadAsUnresolved() {
2639
3072
  const room = useRoom();
2640
3073
  return React4.useCallback(
2641
3074
  (threadId) => {
2642
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2643
3075
  const updatedAt = /* @__PURE__ */ new Date();
2644
3076
  const { store, onMutationFailure } = getExtrasForClient2(client);
2645
- store.pushOptimisticUpdate({
3077
+ const optimisticUpdateId = store.addOptimisticUpdate({
2646
3078
  type: "mark-thread-as-unresolved",
2647
- id: optimisticUpdateId,
2648
3079
  threadId,
2649
3080
  updatedAt
2650
3081
  });
2651
3082
  room.markThreadAsUnresolved(threadId).then(
2652
3083
  () => {
2653
- store.set((state) => {
2654
- const existingThread = state.threads[threadId];
2655
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2656
- (update) => update.id !== optimisticUpdateId
2657
- );
2658
- if (existingThread === void 0) {
2659
- return {
2660
- ...state,
2661
- optimisticUpdates: updatedOptimisticUpdates
2662
- };
2663
- }
2664
- if (existingThread.deletedAt !== void 0) {
2665
- return {
2666
- ...state,
2667
- optimisticUpdates: updatedOptimisticUpdates
2668
- };
2669
- }
2670
- if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
2671
- return {
2672
- ...state,
2673
- optimisticUpdates: updatedOptimisticUpdates
2674
- };
2675
- }
2676
- return {
2677
- ...state,
2678
- threads: {
2679
- ...state.threads,
2680
- [threadId]: {
2681
- ...existingThread,
2682
- resolved: false
2683
- }
2684
- },
2685
- optimisticUpdates: updatedOptimisticUpdates
2686
- };
2687
- });
3084
+ store.updateThread(
3085
+ threadId,
3086
+ optimisticUpdateId,
3087
+ (thread) => ({ ...thread, resolved: false }),
3088
+ updatedAt
3089
+ );
2688
3090
  },
2689
3091
  (err) => onMutationFailure(
2690
3092
  err,
@@ -2704,7 +3106,7 @@ function useThreadSubscription(threadId) {
2704
3106
  const { store } = getExtrasForClient2(client);
2705
3107
  const selector = React4.useCallback(
2706
3108
  (state) => {
2707
- const inboxNotification = selectedInboxNotifications(state).find(
3109
+ const inboxNotification = selectInboxNotifications(state).find(
2708
3110
  (inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
2709
3111
  );
2710
3112
  const thread = state.threads[threadId];
@@ -2830,25 +3232,19 @@ function useUpdateRoomNotificationSettings() {
2830
3232
  const room = useRoom();
2831
3233
  return React4.useCallback(
2832
3234
  (settings) => {
2833
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2834
3235
  const { store, onMutationFailure } = getExtrasForClient2(client);
2835
- store.pushOptimisticUpdate({
2836
- id: optimisticUpdateId,
3236
+ const optimisticUpdateId = store.addOptimisticUpdate({
2837
3237
  type: "update-notification-settings",
2838
3238
  roomId: room.id,
2839
3239
  settings
2840
3240
  });
2841
3241
  room.updateNotificationSettings(settings).then(
2842
3242
  (settings2) => {
2843
- store.set((state) => ({
2844
- ...state,
2845
- notificationSettings: {
2846
- [room.id]: settings2
2847
- },
2848
- optimisticUpdates: state.optimisticUpdates.filter(
2849
- (update) => update.id !== optimisticUpdateId
2850
- )
2851
- }));
3243
+ store.updateRoomInboxNotificationSettings2(
3244
+ room.id,
3245
+ optimisticUpdateId,
3246
+ settings2
3247
+ );
2852
3248
  },
2853
3249
  (err) => onMutationFailure(
2854
3250
  err,
@@ -2937,7 +3333,7 @@ function useThreadsSuspense(options = {
2937
3333
  const selector = React4.useCallback(
2938
3334
  (state2) => {
2939
3335
  return {
2940
- threads: selectedThreads(room.id, state2, options),
3336
+ threads: selectRoomThreads(room.id, state2, options),
2941
3337
  isLoading: false
2942
3338
  };
2943
3339
  },
@@ -3149,5 +3545,6 @@ var _useUpdateMyPresence = useUpdateMyPresence;
3149
3545
 
3150
3546
 
3151
3547
 
3152
- exports.PKG_NAME = PKG_NAME; exports.PKG_VERSION = PKG_VERSION; exports.PKG_FORMAT = PKG_FORMAT; exports.ClientSideSuspense = ClientSideSuspense; exports.selectedThreads = selectedThreads; exports.CreateThreadError = CreateThreadError; exports.RoomContext = RoomContext; exports.useStatus = useStatus; exports.useStorageStatus = useStorageStatus; exports.useBatch = useBatch; exports.useLostConnectionListener = useLostConnectionListener; exports.useErrorListener = useErrorListener; exports.useHistory = useHistory; exports.useUndo = useUndo; exports.useRedo = useRedo; exports.useCanUndo = useCanUndo; exports.useCanRedo = useCanRedo; exports.useOthersConnectionIds = useOthersConnectionIds; exports.useCommentsErrorListener = useCommentsErrorListener; exports.useCreateComment = useCreateComment; exports.useEditComment = useEditComment; exports.useDeleteComment = useDeleteComment; exports.useRemoveReaction = useRemoveReaction; exports.useMarkThreadAsRead = useMarkThreadAsRead; exports.useMarkThreadAsResolved = useMarkThreadAsResolved; exports.useMarkThreadAsUnresolved = useMarkThreadAsUnresolved; exports.useThreadSubscription = useThreadSubscription; exports.useRoomNotificationSettings = useRoomNotificationSettings; exports.useHistoryVersionData = useHistoryVersionData; exports.useUpdateRoomNotificationSettings = useUpdateRoomNotificationSettings; exports.useOthersConnectionIdsSuspense = useOthersConnectionIdsSuspense; exports.useStorageStatusSuspense = useStorageStatusSuspense; exports.createRoomContext = createRoomContext; exports._RoomProvider = _RoomProvider; exports._useBroadcastEvent = _useBroadcastEvent; exports._useOthersListener = _useOthersListener; exports._useRoom = _useRoom; exports._useIsInsideRoom = _useIsInsideRoom; exports._useAddReaction = _useAddReaction; exports._useMutation = _useMutation; exports._useCreateThread = _useCreateThread; exports._useDeleteThread = _useDeleteThread; exports._useEditThreadMetadata = _useEditThreadMetadata; exports._useEventListener = _useEventListener; exports._useMyPresence = _useMyPresence; exports._useOthersMapped = _useOthersMapped; exports._useOthersMappedSuspense = _useOthersMappedSuspense; exports._useThreads = _useThreads; exports._useThreadsSuspense = _useThreadsSuspense; exports._useHistoryVersions = _useHistoryVersions; exports._useHistoryVersionsSuspense = _useHistoryVersionsSuspense; exports._useOther = _useOther; exports._useOthers = _useOthers; exports._useOtherSuspense = _useOtherSuspense; exports._useOthersSuspense = _useOthersSuspense; exports._useStorage = _useStorage; exports._useStorageSuspense = _useStorageSuspense; exports._useSelf = _useSelf; exports._useSelfSuspense = _useSelfSuspense; exports._useStorageRoot = _useStorageRoot; exports._useUpdateMyPresence = _useUpdateMyPresence; exports.ClientContext = ClientContext; exports.useClient = useClient; exports.LiveblocksProvider = LiveblocksProvider; exports.createLiveblocksContext = createLiveblocksContext; exports.useInboxNotifications = useInboxNotifications; exports.useInboxNotificationsSuspense = useInboxNotificationsSuspense; exports.useMarkAllInboxNotificationsAsRead = useMarkAllInboxNotificationsAsRead; exports.useMarkInboxNotificationAsRead = useMarkInboxNotificationAsRead; exports.useDeleteAllInboxNotifications = useDeleteAllInboxNotifications; exports.useDeleteInboxNotification = useDeleteInboxNotification; exports.useUnreadInboxNotificationsCount = useUnreadInboxNotificationsCount; exports.useUnreadInboxNotificationsCountSuspense = useUnreadInboxNotificationsCountSuspense; exports.useRoomInfo = useRoomInfo; exports.useRoomInfoSuspense = useRoomInfoSuspense; exports._useInboxNotificationThread = _useInboxNotificationThread; exports._useUser = _useUser; exports._useUserSuspense = _useUserSuspense; exports._useUserThreads_experimental = _useUserThreads_experimental; exports._useUserThreadsSuspense_experimental = _useUserThreadsSuspense_experimental;
3153
- //# sourceMappingURL=chunk-YGRZXVI6.js.map
3548
+
3549
+ exports.PKG_NAME = PKG_NAME; exports.PKG_VERSION = PKG_VERSION; exports.PKG_FORMAT = PKG_FORMAT; exports.ClientSideSuspense = ClientSideSuspense; exports.CreateThreadError = CreateThreadError; exports.selectRoomThreads = selectRoomThreads; exports.RoomContext = RoomContext; exports.useStatus = useStatus; exports.useStorageStatus = useStorageStatus; exports.useBatch = useBatch; exports.useLostConnectionListener = useLostConnectionListener; exports.useErrorListener = useErrorListener; exports.useHistory = useHistory; exports.useUndo = useUndo; exports.useRedo = useRedo; exports.useCanUndo = useCanUndo; exports.useCanRedo = useCanRedo; exports.useOthersConnectionIds = useOthersConnectionIds; exports.useCommentsErrorListener = useCommentsErrorListener; exports.useCreateComment = useCreateComment; exports.useEditComment = useEditComment; exports.useDeleteComment = useDeleteComment; exports.useRemoveReaction = useRemoveReaction; exports.useMarkThreadAsRead = useMarkThreadAsRead; exports.useMarkThreadAsResolved = useMarkThreadAsResolved; exports.useMarkThreadAsUnresolved = useMarkThreadAsUnresolved; exports.useThreadSubscription = useThreadSubscription; exports.useRoomNotificationSettings = useRoomNotificationSettings; exports.useHistoryVersionData = useHistoryVersionData; exports.useUpdateRoomNotificationSettings = useUpdateRoomNotificationSettings; exports.useOthersConnectionIdsSuspense = useOthersConnectionIdsSuspense; exports.useStorageStatusSuspense = useStorageStatusSuspense; exports.createRoomContext = createRoomContext; exports._RoomProvider = _RoomProvider; exports._useBroadcastEvent = _useBroadcastEvent; exports._useOthersListener = _useOthersListener; exports._useRoom = _useRoom; exports._useIsInsideRoom = _useIsInsideRoom; exports._useAddReaction = _useAddReaction; exports._useMutation = _useMutation; exports._useCreateThread = _useCreateThread; exports._useDeleteThread = _useDeleteThread; exports._useEditThreadMetadata = _useEditThreadMetadata; exports._useEventListener = _useEventListener; exports._useMyPresence = _useMyPresence; exports._useOthersMapped = _useOthersMapped; exports._useOthersMappedSuspense = _useOthersMappedSuspense; exports._useThreads = _useThreads; exports._useThreadsSuspense = _useThreadsSuspense; exports._useHistoryVersions = _useHistoryVersions; exports._useHistoryVersionsSuspense = _useHistoryVersionsSuspense; exports._useOther = _useOther; exports._useOthers = _useOthers; exports._useOtherSuspense = _useOtherSuspense; exports._useOthersSuspense = _useOthersSuspense; exports._useStorage = _useStorage; exports._useStorageSuspense = _useStorageSuspense; exports._useSelf = _useSelf; exports._useSelfSuspense = _useSelfSuspense; exports._useStorageRoot = _useStorageRoot; exports._useUpdateMyPresence = _useUpdateMyPresence; exports.ClientContext = ClientContext; exports.getUmbrellaStoreForClient = getUmbrellaStoreForClient; exports.useClient = useClient; exports.LiveblocksProvider = LiveblocksProvider; exports.createLiveblocksContext = createLiveblocksContext; exports.useInboxNotifications = useInboxNotifications; exports.useInboxNotificationsSuspense = useInboxNotificationsSuspense; exports.useMarkAllInboxNotificationsAsRead = useMarkAllInboxNotificationsAsRead; exports.useMarkInboxNotificationAsRead = useMarkInboxNotificationAsRead; exports.useDeleteAllInboxNotifications = useDeleteAllInboxNotifications; exports.useDeleteInboxNotification = useDeleteInboxNotification; exports.useUnreadInboxNotificationsCount = useUnreadInboxNotificationsCount; exports.useUnreadInboxNotificationsCountSuspense = useUnreadInboxNotificationsCountSuspense; exports.useRoomInfo = useRoomInfo; exports.useRoomInfoSuspense = useRoomInfoSuspense; exports._useInboxNotificationThread = _useInboxNotificationThread; exports._useUser = _useUser; exports._useUserSuspense = _useUserSuspense; exports._useUserThreads_experimental = _useUserThreads_experimental; exports._useUserThreadsSuspense_experimental = _useUserThreadsSuspense_experimental;
3550
+ //# sourceMappingURL=chunk-KNPU4P3Y.js.map