@liveblocks/react 2.7.0-versions → 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-versions";
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();
@@ -1326,13 +1994,10 @@ function makeExtrasForClient2(client) {
1326
1994
  async function getRoomVersions(room, { retryCount } = { retryCount: 0 }) {
1327
1995
  const queryKey = getVersionsQueryKey(room.id);
1328
1996
  const existingRequest = requestsByQuery.get(queryKey);
1329
- _core.console.warn("existing request", existingRequest);
1330
1997
  if (existingRequest !== void 0) return existingRequest;
1331
1998
  const request = room[_core.kInternal].listTextVersions();
1332
1999
  requestsByQuery.set(queryKey, request);
1333
- store.setQueryState(queryKey, {
1334
- isLoading: true
1335
- });
2000
+ store.setQueryLoading(queryKey);
1336
2001
  try {
1337
2002
  const result = await request;
1338
2003
  const data = await result.json();
@@ -1351,10 +2016,7 @@ function makeExtrasForClient2(client) {
1351
2016
  retryCount: retryCount + 1
1352
2017
  });
1353
2018
  }, retryCount);
1354
- store.setQueryState(queryKey, {
1355
- isLoading: false,
1356
- error: err
1357
- });
2019
+ store.setQueryError(queryKey, err);
1358
2020
  }
1359
2021
  return;
1360
2022
  }
@@ -1363,9 +2025,7 @@ function makeExtrasForClient2(client) {
1363
2025
  if (existingRequest !== void 0) return existingRequest;
1364
2026
  const request = room.getThreads(options);
1365
2027
  requestsByQuery.set(queryKey, request);
1366
- store.setQueryState(queryKey, {
1367
- isLoading: true
1368
- });
2028
+ store.setQueryLoading(queryKey);
1369
2029
  try {
1370
2030
  const result = await request;
1371
2031
  store.updateThreadsAndNotifications(
@@ -1388,10 +2048,7 @@ function makeExtrasForClient2(client) {
1388
2048
  retryCount: retryCount + 1
1389
2049
  });
1390
2050
  }, retryCount);
1391
- store.setQueryState(queryKey, {
1392
- isLoading: false,
1393
- error: err
1394
- });
2051
+ store.setQueryError(queryKey, err);
1395
2052
  }
1396
2053
  return;
1397
2054
  }
@@ -1401,9 +2058,7 @@ function makeExtrasForClient2(client) {
1401
2058
  try {
1402
2059
  const request = room.getNotificationSettings();
1403
2060
  requestsByQuery.set(queryKey, request);
1404
- store.setQueryState(queryKey, {
1405
- isLoading: true
1406
- });
2061
+ store.setQueryLoading(queryKey);
1407
2062
  const settings = await request;
1408
2063
  store.updateRoomInboxNotificationSettings(room.id, settings, queryKey);
1409
2064
  } catch (err) {
@@ -1413,21 +2068,13 @@ function makeExtrasForClient2(client) {
1413
2068
  retryCount: retryCount + 1
1414
2069
  });
1415
2070
  }, retryCount);
1416
- store.setQueryState(queryKey, {
1417
- isLoading: false,
1418
- error: err
1419
- });
2071
+ store.setQueryError(queryKey, err);
1420
2072
  }
1421
2073
  return;
1422
2074
  }
1423
2075
  const commentsErrorEventSource = _core.makeEventSource.call(void 0, );
1424
2076
  function onMutationFailure(innerError, optimisticUpdateId, createPublicError) {
1425
- store.set((state) => ({
1426
- ...state,
1427
- optimisticUpdates: state.optimisticUpdates.filter(
1428
- (update) => update.id !== optimisticUpdateId
1429
- )
1430
- }));
2077
+ store.removeOptimisticUpdate(optimisticUpdateId);
1431
2078
  if (innerError instanceof _core.CommentsApiError) {
1432
2079
  const error = handleApiError(innerError);
1433
2080
  commentsErrorEventSource.notify(createPublicError(error));
@@ -1590,7 +2237,7 @@ function RoomProviderInner(props) {
1590
2237
  "RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required"
1591
2238
  );
1592
2239
  }
1593
- if (typeof roomId !== "string") {
2240
+ if (!isString(roomId)) {
1594
2241
  throw new Error("RoomProvider id property should be a string.");
1595
2242
  }
1596
2243
  const majorReactVersion = parseInt(React4.version) || 1;
@@ -1621,12 +2268,12 @@ function RoomProviderInner(props) {
1621
2268
  const { store } = getExtrasForClient2(client);
1622
2269
  async function handleCommentEvent(message) {
1623
2270
  if (message.type === _core.ServerMsgCode.THREAD_DELETED) {
1624
- store.deleteThread(message.threadId);
2271
+ store.deleteThread(message.threadId, null);
1625
2272
  return;
1626
2273
  }
1627
2274
  const info = await room.getThread(message.threadId);
1628
2275
  if (!info.thread) {
1629
- store.deleteThread(message.threadId);
2276
+ store.deleteThread(message.threadId, null);
1630
2277
  return;
1631
2278
  }
1632
2279
  const { thread, inboxNotification } = info;
@@ -1698,7 +2345,7 @@ function useStatus() {
1698
2345
  return useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot);
1699
2346
  }
1700
2347
  function useStorageStatus(options) {
1701
- const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _7 => _7.smooth]), () => ( false)));
2348
+ const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _22 => _22.smooth]), () => ( false)));
1702
2349
  if (smooth) {
1703
2350
  return useStorageStatusSmooth();
1704
2351
  } else {
@@ -1975,7 +2622,7 @@ function useThreads(options = {
1975
2622
  };
1976
2623
  }
1977
2624
  return {
1978
- threads: selectedThreads(room.id, state2, options),
2625
+ threads: selectRoomThreads(room.id, state2, options),
1979
2626
  isLoading: false,
1980
2627
  error: query.error
1981
2628
  };
@@ -2030,26 +2677,15 @@ function useCreateThread() {
2030
2677
  comments: [newComment],
2031
2678
  resolved: false
2032
2679
  };
2033
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2034
2680
  const { store, onMutationFailure } = getExtrasForClient2(client);
2035
- store.pushOptimisticUpdate({
2681
+ const optimisticUpdateId = store.addOptimisticUpdate({
2036
2682
  type: "create-thread",
2037
2683
  thread: newThread,
2038
- id: optimisticUpdateId,
2039
2684
  roomId: room.id
2040
2685
  });
2041
2686
  room.createThread({ threadId, commentId, body, metadata }).then(
2042
2687
  (thread) => {
2043
- store.set((state) => ({
2044
- ...state,
2045
- threads: {
2046
- ...state.threads,
2047
- [threadId]: thread
2048
- },
2049
- optimisticUpdates: state.optimisticUpdates.filter(
2050
- (update) => update.id !== optimisticUpdateId
2051
- )
2052
- }));
2688
+ store.createThread(optimisticUpdateId, thread);
2053
2689
  },
2054
2690
  (err) => onMutationFailure(
2055
2691
  err,
@@ -2073,42 +2709,21 @@ function useDeleteThread() {
2073
2709
  const room = useRoom();
2074
2710
  return React4.useCallback(
2075
2711
  (threadId) => {
2076
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2077
2712
  const { store, onMutationFailure } = getExtrasForClient2(client);
2078
2713
  const thread = store.get().threads[threadId];
2079
2714
  const userId = getCurrentUserId(room);
2080
- 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) {
2081
2716
  throw new Error("Only the thread creator can delete the thread");
2082
2717
  }
2083
- store.pushOptimisticUpdate({
2718
+ const optimisticUpdateId = store.addOptimisticUpdate({
2084
2719
  type: "delete-thread",
2085
- id: optimisticUpdateId,
2086
2720
  roomId: room.id,
2087
2721
  threadId,
2088
2722
  deletedAt: /* @__PURE__ */ new Date()
2089
2723
  });
2090
2724
  room.deleteThread(threadId).then(
2091
2725
  () => {
2092
- store.set((state) => {
2093
- const existingThread = state.threads[threadId];
2094
- if (existingThread === void 0) {
2095
- return state;
2096
- }
2097
- return {
2098
- ...state,
2099
- threads: {
2100
- ...state.threads,
2101
- [threadId]: {
2102
- ...existingThread,
2103
- updatedAt: /* @__PURE__ */ new Date(),
2104
- deletedAt: /* @__PURE__ */ new Date()
2105
- }
2106
- },
2107
- optimisticUpdates: state.optimisticUpdates.filter(
2108
- (update) => update.id !== optimisticUpdateId
2109
- )
2110
- };
2111
- });
2726
+ store.deleteThread(threadId, optimisticUpdateId);
2112
2727
  },
2113
2728
  (err) => onMutationFailure(
2114
2729
  err,
@@ -2131,53 +2746,23 @@ function useEditThreadMetadata() {
2131
2746
  const threadId = options.threadId;
2132
2747
  const metadata = options.metadata;
2133
2748
  const updatedAt = /* @__PURE__ */ new Date();
2134
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2135
2749
  const { store, onMutationFailure } = getExtrasForClient2(client);
2136
- store.pushOptimisticUpdate({
2750
+ const optimisticUpdateId = store.addOptimisticUpdate({
2137
2751
  type: "edit-thread-metadata",
2138
2752
  metadata,
2139
- id: optimisticUpdateId,
2140
2753
  threadId,
2141
2754
  updatedAt
2142
2755
  });
2143
- room.editThreadMetadata({ metadata, threadId }).then(
2144
- (metadata2) => {
2145
- store.set((state) => {
2146
- const existingThread = state.threads[threadId];
2147
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2148
- (update) => update.id !== optimisticUpdateId
2149
- );
2150
- if (existingThread === void 0) {
2151
- return {
2152
- ...state,
2153
- optimisticUpdates: updatedOptimisticUpdates
2154
- };
2155
- }
2156
- if (existingThread.deletedAt !== void 0) {
2157
- return {
2158
- ...state,
2159
- optimisticUpdates: updatedOptimisticUpdates
2160
- };
2161
- }
2162
- if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
2163
- return {
2164
- ...state,
2165
- optimisticUpdates: updatedOptimisticUpdates
2166
- };
2167
- }
2168
- return {
2169
- ...state,
2170
- threads: {
2171
- ...state.threads,
2172
- [threadId]: {
2173
- ...existingThread,
2174
- metadata: metadata2
2175
- }
2176
- },
2177
- optimisticUpdates: updatedOptimisticUpdates
2178
- };
2179
- });
2180
- },
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
+ ),
2181
2766
  (err) => onMutationFailure(
2182
2767
  err,
2183
2768
  optimisticUpdateId,
@@ -2209,50 +2794,14 @@ function useCreateComment() {
2209
2794
  body,
2210
2795
  reactions: []
2211
2796
  };
2212
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2213
2797
  const { store, onMutationFailure } = getExtrasForClient2(client);
2214
- store.pushOptimisticUpdate({
2798
+ const optimisticUpdateId = store.addOptimisticUpdate({
2215
2799
  type: "create-comment",
2216
- comment,
2217
- id: optimisticUpdateId
2800
+ comment
2218
2801
  });
2219
2802
  room.createComment({ threadId, commentId, body }).then(
2220
2803
  (newComment) => {
2221
- store.set((state) => {
2222
- const existingThread = state.threads[threadId];
2223
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2224
- (update) => update.id !== optimisticUpdateId
2225
- );
2226
- if (existingThread === void 0) {
2227
- return {
2228
- ...state,
2229
- optimisticUpdates: updatedOptimisticUpdates
2230
- };
2231
- }
2232
- const inboxNotification = Object.values(
2233
- state.inboxNotifications
2234
- ).find(
2235
- (notification) => notification.kind === "thread" && notification.threadId === threadId
2236
- );
2237
- const updatedInboxNotifications = inboxNotification !== void 0 ? {
2238
- ...state.inboxNotifications,
2239
- [inboxNotification.id]: {
2240
- ...inboxNotification,
2241
- notifiedAt: newComment.createdAt,
2242
- readAt: newComment.createdAt
2243
- }
2244
- } : state.inboxNotifications;
2245
- return {
2246
- ...state,
2247
- threads: {
2248
- ...state.threads,
2249
- [threadId]: _core.upsertComment.call(void 0, existingThread, newComment)
2250
- // Upsert the new comment into the thread comments list (if applicable)
2251
- },
2252
- inboxNotifications: updatedInboxNotifications,
2253
- optimisticUpdates: updatedOptimisticUpdates
2254
- };
2255
- });
2804
+ store.createComment(newComment, optimisticUpdateId);
2256
2805
  },
2257
2806
  (err) => onMutationFailure(
2258
2807
  err,
@@ -2276,7 +2825,6 @@ function useEditComment() {
2276
2825
  return React4.useCallback(
2277
2826
  ({ threadId, commentId, body }) => {
2278
2827
  const editedAt = /* @__PURE__ */ new Date();
2279
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2280
2828
  const { store, onMutationFailure } = getExtrasForClient2(client);
2281
2829
  const thread = store.get().threads[threadId];
2282
2830
  if (thread === void 0) {
@@ -2294,38 +2842,21 @@ function useEditComment() {
2294
2842
  );
2295
2843
  return;
2296
2844
  }
2297
- store.pushOptimisticUpdate({
2845
+ const optimisticUpdateId = store.addOptimisticUpdate({
2298
2846
  type: "edit-comment",
2299
2847
  comment: {
2300
2848
  ...comment,
2301
2849
  editedAt,
2302
2850
  body
2303
- },
2304
- id: optimisticUpdateId
2851
+ }
2305
2852
  });
2306
2853
  room.editComment({ threadId, commentId, body }).then(
2307
2854
  (editedComment) => {
2308
- store.set((state) => {
2309
- const existingThread = state.threads[threadId];
2310
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2311
- (update) => update.id !== optimisticUpdateId
2312
- );
2313
- if (existingThread === void 0) {
2314
- return {
2315
- ...state,
2316
- optimisticUpdates: updatedOptimisticUpdates
2317
- };
2318
- }
2319
- return {
2320
- ...state,
2321
- threads: {
2322
- ...state.threads,
2323
- [threadId]: _core.upsertComment.call(void 0, existingThread, editedComment)
2324
- // Upsert the edited comment into the thread comments list (if applicable)
2325
- },
2326
- optimisticUpdates: updatedOptimisticUpdates
2327
- };
2328
- });
2855
+ store.updateThread(
2856
+ threadId,
2857
+ optimisticUpdateId,
2858
+ (thread2) => upsertComment(thread2, editedComment)
2859
+ );
2329
2860
  },
2330
2861
  (err) => onMutationFailure(
2331
2862
  err,
@@ -2348,38 +2879,22 @@ function useDeleteComment() {
2348
2879
  return React4.useCallback(
2349
2880
  ({ threadId, commentId }) => {
2350
2881
  const deletedAt = /* @__PURE__ */ new Date();
2351
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2352
2882
  const { store, onMutationFailure } = getExtrasForClient2(client);
2353
- store.pushOptimisticUpdate({
2883
+ const optimisticUpdateId = store.addOptimisticUpdate({
2354
2884
  type: "delete-comment",
2355
2885
  threadId,
2356
2886
  commentId,
2357
2887
  deletedAt,
2358
- id: optimisticUpdateId,
2359
2888
  roomId: room.id
2360
2889
  });
2361
2890
  room.deleteComment({ threadId, commentId }).then(
2362
2891
  () => {
2363
- store.set((state) => {
2364
- const existingThread = state.threads[threadId];
2365
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2366
- (update) => update.id !== optimisticUpdateId
2367
- );
2368
- if (existingThread === void 0) {
2369
- return {
2370
- ...state,
2371
- optimisticUpdates: updatedOptimisticUpdates
2372
- };
2373
- }
2374
- return {
2375
- ...state,
2376
- threads: {
2377
- ...state.threads,
2378
- [threadId]: _core.deleteComment.call(void 0, existingThread, commentId, deletedAt)
2379
- },
2380
- optimisticUpdates: updatedOptimisticUpdates
2381
- };
2382
- });
2892
+ store.updateThread(
2893
+ threadId,
2894
+ optimisticUpdateId,
2895
+ (thread) => deleteComment(thread, commentId, deletedAt),
2896
+ deletedAt
2897
+ );
2383
2898
  },
2384
2899
  (err) => onMutationFailure(
2385
2900
  err,
@@ -2402,9 +2917,8 @@ function useAddReaction() {
2402
2917
  ({ threadId, commentId, emoji }) => {
2403
2918
  const createdAt = /* @__PURE__ */ new Date();
2404
2919
  const userId = getCurrentUserId(room);
2405
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2406
2920
  const { store, onMutationFailure } = getExtrasForClient2(client);
2407
- store.pushOptimisticUpdate({
2921
+ const optimisticUpdateId = store.addOptimisticUpdate({
2408
2922
  type: "add-reaction",
2409
2923
  threadId,
2410
2924
  commentId,
@@ -2412,35 +2926,16 @@ function useAddReaction() {
2412
2926
  emoji,
2413
2927
  userId,
2414
2928
  createdAt
2415
- },
2416
- id: optimisticUpdateId
2929
+ }
2417
2930
  });
2418
2931
  room.addReaction({ threadId, commentId, emoji }).then(
2419
2932
  (addedReaction) => {
2420
- store.set((state) => {
2421
- const existingThread = state.threads[threadId];
2422
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2423
- (update) => update.id !== optimisticUpdateId
2424
- );
2425
- if (existingThread === void 0) {
2426
- return {
2427
- ...state,
2428
- optimisticUpdates: updatedOptimisticUpdates
2429
- };
2430
- }
2431
- return {
2432
- ...state,
2433
- threads: {
2434
- ...state.threads,
2435
- [threadId]: _core.addReaction.call(void 0,
2436
- existingThread,
2437
- commentId,
2438
- addedReaction
2439
- )
2440
- },
2441
- optimisticUpdates: updatedOptimisticUpdates
2442
- };
2443
- });
2933
+ store.updateThread(
2934
+ threadId,
2935
+ optimisticUpdateId,
2936
+ (thread) => addReaction(thread, commentId, addedReaction),
2937
+ createdAt
2938
+ );
2444
2939
  },
2445
2940
  (err) => onMutationFailure(
2446
2941
  err,
@@ -2464,45 +2959,23 @@ function useRemoveReaction() {
2464
2959
  ({ threadId, commentId, emoji }) => {
2465
2960
  const userId = getCurrentUserId(room);
2466
2961
  const removedAt = /* @__PURE__ */ new Date();
2467
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2468
2962
  const { store, onMutationFailure } = getExtrasForClient2(client);
2469
- store.pushOptimisticUpdate({
2963
+ const optimisticUpdateId = store.addOptimisticUpdate({
2470
2964
  type: "remove-reaction",
2471
2965
  threadId,
2472
2966
  commentId,
2473
2967
  emoji,
2474
2968
  userId,
2475
- removedAt,
2476
- id: optimisticUpdateId
2969
+ removedAt
2477
2970
  });
2478
2971
  room.removeReaction({ threadId, commentId, emoji }).then(
2479
2972
  () => {
2480
- store.set((state) => {
2481
- const existingThread = state.threads[threadId];
2482
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2483
- (update) => update.id !== optimisticUpdateId
2484
- );
2485
- if (existingThread === void 0) {
2486
- return {
2487
- ...state,
2488
- optimisticUpdates: updatedOptimisticUpdates
2489
- };
2490
- }
2491
- return {
2492
- ...state,
2493
- threads: {
2494
- ...state.threads,
2495
- [threadId]: _core.removeReaction.call(void 0,
2496
- existingThread,
2497
- commentId,
2498
- emoji,
2499
- userId,
2500
- removedAt
2501
- )
2502
- },
2503
- optimisticUpdates: updatedOptimisticUpdates
2504
- };
2505
- });
2973
+ store.updateThread(
2974
+ threadId,
2975
+ optimisticUpdateId,
2976
+ (thread) => removeReaction(thread, commentId, emoji, userId, removedAt),
2977
+ removedAt
2978
+ );
2506
2979
  },
2507
2980
  (err) => onMutationFailure(
2508
2981
  err,
@@ -2531,29 +3004,19 @@ function useMarkThreadAsRead() {
2531
3004
  (inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
2532
3005
  );
2533
3006
  if (!inboxNotification) return;
2534
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2535
3007
  const now = /* @__PURE__ */ new Date();
2536
- store.pushOptimisticUpdate({
3008
+ const optimisticUpdateId = store.addOptimisticUpdate({
2537
3009
  type: "mark-inbox-notification-as-read",
2538
- id: optimisticUpdateId,
2539
3010
  inboxNotificationId: inboxNotification.id,
2540
3011
  readAt: now
2541
3012
  });
2542
3013
  room.markInboxNotificationAsRead(inboxNotification.id).then(
2543
3014
  () => {
2544
- store.set((state) => ({
2545
- ...state,
2546
- inboxNotifications: {
2547
- ...state.inboxNotifications,
2548
- [inboxNotification.id]: {
2549
- ...inboxNotification,
2550
- readAt: now
2551
- }
2552
- },
2553
- optimisticUpdates: state.optimisticUpdates.filter(
2554
- (update) => update.id !== optimisticUpdateId
2555
- )
2556
- }));
3015
+ store.updateInboxNotification(
3016
+ inboxNotification.id,
3017
+ optimisticUpdateId,
3018
+ (inboxNotification2) => ({ ...inboxNotification2, readAt: now })
3019
+ );
2557
3020
  },
2558
3021
  (err) => {
2559
3022
  onMutationFailure(
@@ -2575,52 +3038,21 @@ function useMarkThreadAsResolved() {
2575
3038
  const room = useRoom();
2576
3039
  return React4.useCallback(
2577
3040
  (threadId) => {
2578
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2579
3041
  const updatedAt = /* @__PURE__ */ new Date();
2580
3042
  const { store, onMutationFailure } = getExtrasForClient2(client);
2581
- store.pushOptimisticUpdate({
3043
+ const optimisticUpdateId = store.addOptimisticUpdate({
2582
3044
  type: "mark-thread-as-resolved",
2583
- id: optimisticUpdateId,
2584
3045
  threadId,
2585
3046
  updatedAt
2586
3047
  });
2587
3048
  room.markThreadAsResolved(threadId).then(
2588
3049
  () => {
2589
- store.set((state) => {
2590
- const existingThread = state.threads[threadId];
2591
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2592
- (update) => update.id !== optimisticUpdateId
2593
- );
2594
- if (existingThread === void 0) {
2595
- return {
2596
- ...state,
2597
- optimisticUpdates: updatedOptimisticUpdates
2598
- };
2599
- }
2600
- if (existingThread.deletedAt !== void 0) {
2601
- return {
2602
- ...state,
2603
- optimisticUpdates: updatedOptimisticUpdates
2604
- };
2605
- }
2606
- if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
2607
- return {
2608
- ...state,
2609
- optimisticUpdates: updatedOptimisticUpdates
2610
- };
2611
- }
2612
- return {
2613
- ...state,
2614
- threads: {
2615
- ...state.threads,
2616
- [threadId]: {
2617
- ...existingThread,
2618
- resolved: true
2619
- }
2620
- },
2621
- optimisticUpdates: updatedOptimisticUpdates
2622
- };
2623
- });
3050
+ store.updateThread(
3051
+ threadId,
3052
+ optimisticUpdateId,
3053
+ (thread) => ({ ...thread, resolved: true }),
3054
+ updatedAt
3055
+ );
2624
3056
  },
2625
3057
  (err) => onMutationFailure(
2626
3058
  err,
@@ -2640,52 +3072,21 @@ function useMarkThreadAsUnresolved() {
2640
3072
  const room = useRoom();
2641
3073
  return React4.useCallback(
2642
3074
  (threadId) => {
2643
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2644
3075
  const updatedAt = /* @__PURE__ */ new Date();
2645
3076
  const { store, onMutationFailure } = getExtrasForClient2(client);
2646
- store.pushOptimisticUpdate({
3077
+ const optimisticUpdateId = store.addOptimisticUpdate({
2647
3078
  type: "mark-thread-as-unresolved",
2648
- id: optimisticUpdateId,
2649
3079
  threadId,
2650
3080
  updatedAt
2651
3081
  });
2652
3082
  room.markThreadAsUnresolved(threadId).then(
2653
3083
  () => {
2654
- store.set((state) => {
2655
- const existingThread = state.threads[threadId];
2656
- const updatedOptimisticUpdates = state.optimisticUpdates.filter(
2657
- (update) => update.id !== optimisticUpdateId
2658
- );
2659
- if (existingThread === void 0) {
2660
- return {
2661
- ...state,
2662
- optimisticUpdates: updatedOptimisticUpdates
2663
- };
2664
- }
2665
- if (existingThread.deletedAt !== void 0) {
2666
- return {
2667
- ...state,
2668
- optimisticUpdates: updatedOptimisticUpdates
2669
- };
2670
- }
2671
- if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
2672
- return {
2673
- ...state,
2674
- optimisticUpdates: updatedOptimisticUpdates
2675
- };
2676
- }
2677
- return {
2678
- ...state,
2679
- threads: {
2680
- ...state.threads,
2681
- [threadId]: {
2682
- ...existingThread,
2683
- resolved: false
2684
- }
2685
- },
2686
- optimisticUpdates: updatedOptimisticUpdates
2687
- };
2688
- });
3084
+ store.updateThread(
3085
+ threadId,
3086
+ optimisticUpdateId,
3087
+ (thread) => ({ ...thread, resolved: false }),
3088
+ updatedAt
3089
+ );
2689
3090
  },
2690
3091
  (err) => onMutationFailure(
2691
3092
  err,
@@ -2705,7 +3106,7 @@ function useThreadSubscription(threadId) {
2705
3106
  const { store } = getExtrasForClient2(client);
2706
3107
  const selector = React4.useCallback(
2707
3108
  (state) => {
2708
- const inboxNotification = selectedInboxNotifications(state).find(
3109
+ const inboxNotification = selectInboxNotifications(state).find(
2709
3110
  (inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
2710
3111
  );
2711
3112
  const thread = state.threads[threadId];
@@ -2831,25 +3232,19 @@ function useUpdateRoomNotificationSettings() {
2831
3232
  const room = useRoom();
2832
3233
  return React4.useCallback(
2833
3234
  (settings) => {
2834
- const optimisticUpdateId = _core.nanoid.call(void 0, );
2835
3235
  const { store, onMutationFailure } = getExtrasForClient2(client);
2836
- store.pushOptimisticUpdate({
2837
- id: optimisticUpdateId,
3236
+ const optimisticUpdateId = store.addOptimisticUpdate({
2838
3237
  type: "update-notification-settings",
2839
3238
  roomId: room.id,
2840
3239
  settings
2841
3240
  });
2842
3241
  room.updateNotificationSettings(settings).then(
2843
3242
  (settings2) => {
2844
- store.set((state) => ({
2845
- ...state,
2846
- notificationSettings: {
2847
- [room.id]: settings2
2848
- },
2849
- optimisticUpdates: state.optimisticUpdates.filter(
2850
- (update) => update.id !== optimisticUpdateId
2851
- )
2852
- }));
3243
+ store.updateRoomInboxNotificationSettings2(
3244
+ room.id,
3245
+ optimisticUpdateId,
3246
+ settings2
3247
+ );
2853
3248
  },
2854
3249
  (err) => onMutationFailure(
2855
3250
  err,
@@ -2938,7 +3333,7 @@ function useThreadsSuspense(options = {
2938
3333
  const selector = React4.useCallback(
2939
3334
  (state2) => {
2940
3335
  return {
2941
- threads: selectedThreads(room.id, state2, options),
3336
+ threads: selectRoomThreads(room.id, state2, options),
2942
3337
  isLoading: false
2943
3338
  };
2944
3339
  },
@@ -3150,5 +3545,6 @@ var _useUpdateMyPresence = useUpdateMyPresence;
3150
3545
 
3151
3546
 
3152
3547
 
3153
- 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;
3154
- //# sourceMappingURL=chunk-GN5SQAIY.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