@liveblocks/react 2.13.3-emails1 → 2.14.0-lexical1

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.
@@ -132,6 +132,8 @@ var use = (
132
132
 
133
133
 
134
134
 
135
+
136
+
135
137
  // src/lib/autobind.ts
136
138
  function autobind(self) {
137
139
  const seen = /* @__PURE__ */ new Set();
@@ -202,36 +204,35 @@ function sanitizeThread(thread) {
202
204
  return thread;
203
205
  }
204
206
  var ThreadDB = class _ThreadDB {
205
- // The version is auto-incremented on every mutation and can be used as a reliable indicator to tell if the contents of the thread pool has changed
207
+ #byId;
208
+ #asc;
209
+ #desc;
210
+ // This signal will be notified on every mutation
211
+
206
212
  constructor() {
207
- this._asc = _core.SortedList.from([], (t1, t2) => {
213
+ this.#asc = _core.SortedList.from([], (t1, t2) => {
208
214
  const d1 = t1.createdAt;
209
215
  const d2 = t2.createdAt;
210
216
  return d1 < d2 ? true : d1 === d2 ? t1.id < t2.id : false;
211
217
  });
212
- this._desc = _core.SortedList.from([], (t1, t2) => {
218
+ this.#desc = _core.SortedList.from([], (t1, t2) => {
213
219
  const d2 = t2.updatedAt;
214
220
  const d1 = t1.updatedAt;
215
221
  return d2 < d1 ? true : d2 === d1 ? t2.id < t1.id : false;
216
222
  });
217
- this._byId = /* @__PURE__ */ new Map();
218
- this._version = 0;
223
+ this.#byId = /* @__PURE__ */ new Map();
224
+ this.signal = new (0, _core.MutableSignal)(this);
219
225
  }
220
226
  //
221
227
  // Public APIs
222
228
  //
223
229
  clone() {
224
230
  const newPool = new _ThreadDB();
225
- newPool._byId = new Map(this._byId);
226
- newPool._asc = this._asc.clone();
227
- newPool._desc = this._desc.clone();
228
- newPool._version = this._version;
231
+ newPool.#byId = new Map(this.#byId);
232
+ newPool.#asc = this.#asc.clone();
233
+ newPool.#desc = this.#desc.clone();
229
234
  return newPool;
230
235
  }
231
- /** Gets the transaction count for this DB. Increments any time the DB is modified. */
232
- get version() {
233
- return this._version;
234
- }
235
236
  /** Returns an existing thread by ID. Will never return a deleted thread. */
236
237
  get(threadId) {
237
238
  const thread = this.getEvenIfDeleted(threadId);
@@ -239,24 +240,26 @@ var ThreadDB = class _ThreadDB {
239
240
  }
240
241
  /** Returns the (possibly deleted) thread by ID. */
241
242
  getEvenIfDeleted(threadId) {
242
- return this._byId.get(threadId);
243
+ return this.#byId.get(threadId);
243
244
  }
244
245
  /** Adds or updates a thread in the DB. If the newly given thread is a deleted one, it will get deleted. */
245
246
  upsert(thread) {
246
- thread = sanitizeThread(thread);
247
- const id = thread.id;
248
- const toRemove = this._byId.get(id);
249
- if (toRemove) {
250
- if (toRemove.deletedAt) return;
251
- this._asc.remove(toRemove);
252
- this._desc.remove(toRemove);
253
- }
254
- if (!thread.deletedAt) {
255
- this._asc.add(thread);
256
- this._desc.add(thread);
257
- }
258
- this._byId.set(id, thread);
259
- this.touch();
247
+ this.signal.mutate(() => {
248
+ thread = sanitizeThread(thread);
249
+ const id = thread.id;
250
+ const toRemove = this.#byId.get(id);
251
+ if (toRemove) {
252
+ if (toRemove.deletedAt) return false;
253
+ this.#asc.remove(toRemove);
254
+ this.#desc.remove(toRemove);
255
+ }
256
+ if (!thread.deletedAt) {
257
+ this.#asc.add(thread);
258
+ this.#desc.add(thread);
259
+ }
260
+ this.#byId.set(id, thread);
261
+ return true;
262
+ });
260
263
  }
261
264
  /** Like .upsert(), except it won't update if a thread by this ID already exists. */
262
265
  // TODO Consider renaming this to just .upsert(). I'm not sure if we really
@@ -272,7 +275,7 @@ var ThreadDB = class _ThreadDB {
272
275
  * queries, but it can still be accessed via `.getEvenIfDeleted()`.
273
276
  */
274
277
  delete(threadId, deletedAt) {
275
- const existing = this._byId.get(threadId);
278
+ const existing = this.#byId.get(threadId);
276
279
  if (existing && !existing.deletedAt) {
277
280
  this.upsert({ ...existing, deletedAt, updatedAt: deletedAt });
278
281
  }
@@ -289,7 +292,7 @@ var ThreadDB = class _ThreadDB {
289
292
  * Will never return deleted threads in the result.
290
293
  */
291
294
  findMany(roomId, query, direction) {
292
- const index = direction === "desc" ? this._desc : this._asc;
295
+ const index = direction === "desc" ? this.#desc : this.#asc;
293
296
  const crit = [];
294
297
  if (roomId !== void 0) {
295
298
  crit.push((t) => t.roomId === roomId);
@@ -297,12 +300,6 @@ var ThreadDB = class _ThreadDB {
297
300
  crit.push(makeThreadsFilter(query));
298
301
  return Array.from(index.filter((t) => crit.every((pred) => pred(t))));
299
302
  }
300
- //
301
- // Private APIs
302
- //
303
- touch() {
304
- ++this._version;
305
- }
306
303
  };
307
304
 
308
305
  // src/umbrella-store.ts
@@ -339,62 +336,67 @@ function usify(promise) {
339
336
  var noop2 = Promise.resolve();
340
337
  var ASYNC_LOADING = Object.freeze({ isLoading: true });
341
338
  var PaginatedResource = class {
339
+
340
+ #eventSource;
341
+ #fetchPage;
342
+ #paginationState;
343
+ // Should be null while in loading or error state!
344
+ #pendingFetchMore;
342
345
  constructor(fetchPage) {
343
- this._cachedPromise = null;
344
- this._paginationState = null;
345
- this._fetchPage = fetchPage;
346
- this._eventSource = _core.makeEventSource.call(void 0, );
347
- this._pendingFetchMore = null;
348
- this.observable = this._eventSource.observable;
346
+ this.#paginationState = null;
347
+ this.#fetchPage = fetchPage;
348
+ this.#eventSource = _core.makeEventSource.call(void 0, );
349
+ this.#pendingFetchMore = null;
350
+ this.observable = this.#eventSource.observable;
349
351
  autobind(this);
350
352
  }
351
- patchPaginationState(patch) {
352
- const state = this._paginationState;
353
+ #patchPaginationState(patch) {
354
+ const state = this.#paginationState;
353
355
  if (state === null) return;
354
- this._paginationState = { ...state, ...patch };
355
- this._eventSource.notify();
356
+ this.#paginationState = { ...state, ...patch };
357
+ this.#eventSource.notify();
356
358
  }
357
- async _fetchMore() {
358
- const state = this._paginationState;
359
+ async #fetchMore() {
360
+ const state = this.#paginationState;
359
361
  if (!_optionalChain([state, 'optionalAccess', _3 => _3.cursor])) {
360
362
  return;
361
363
  }
362
- this.patchPaginationState({ isFetchingMore: true });
364
+ this.#patchPaginationState({ isFetchingMore: true });
363
365
  try {
364
- const nextCursor = await this._fetchPage(state.cursor);
365
- this.patchPaginationState({
366
+ const nextCursor = await this.#fetchPage(state.cursor);
367
+ this.#patchPaginationState({
366
368
  cursor: nextCursor,
367
369
  fetchMoreError: void 0,
368
370
  isFetchingMore: false
369
371
  });
370
372
  } catch (err) {
371
- this.patchPaginationState({
373
+ this.#patchPaginationState({
372
374
  isFetchingMore: false,
373
375
  fetchMoreError: err
374
376
  });
375
377
  }
376
378
  }
377
379
  fetchMore() {
378
- const state = this._paginationState;
380
+ const state = this.#paginationState;
379
381
  if (_optionalChain([state, 'optionalAccess', _4 => _4.cursor]) === null) {
380
382
  return noop2;
381
383
  }
382
- if (!this._pendingFetchMore) {
383
- this._pendingFetchMore = this._fetchMore().finally(() => {
384
- this._pendingFetchMore = null;
384
+ if (!this.#pendingFetchMore) {
385
+ this.#pendingFetchMore = this.#fetchMore().finally(() => {
386
+ this.#pendingFetchMore = null;
385
387
  });
386
388
  }
387
- return this._pendingFetchMore;
389
+ return this.#pendingFetchMore;
388
390
  }
389
391
  get() {
390
- const usable = this._cachedPromise;
392
+ const usable = this.#cachedPromise;
391
393
  if (usable === null || usable.status === "pending") {
392
394
  return ASYNC_LOADING;
393
395
  }
394
396
  if (usable.status === "rejected") {
395
397
  return { isLoading: false, error: usable.reason };
396
398
  }
397
- const state = this._paginationState;
399
+ const state = this.#paginationState;
398
400
  return {
399
401
  isLoading: false,
400
402
  data: {
@@ -405,12 +407,13 @@ var PaginatedResource = class {
405
407
  }
406
408
  };
407
409
  }
410
+ #cachedPromise = null;
408
411
  waitUntilLoaded() {
409
- if (this._cachedPromise) {
410
- return this._cachedPromise;
412
+ if (this.#cachedPromise) {
413
+ return this.#cachedPromise;
411
414
  }
412
415
  const initialFetcher = _core.autoRetry.call(void 0,
413
- () => this._fetchPage(
416
+ () => this.#fetchPage(
414
417
  /* cursor */
415
418
  void 0
416
419
  ),
@@ -419,7 +422,7 @@ var PaginatedResource = class {
419
422
  );
420
423
  const promise = usify(
421
424
  initialFetcher.then((cursor) => {
422
- this._paginationState = {
425
+ this.#paginationState = {
423
426
  cursor,
424
427
  isFetchingMore: false,
425
428
  fetchMoreError: void 0
@@ -427,29 +430,31 @@ var PaginatedResource = class {
427
430
  })
428
431
  );
429
432
  promise.then(
430
- () => this._eventSource.notify(),
433
+ () => this.#eventSource.notify(),
431
434
  () => {
432
- this._eventSource.notify();
435
+ this.#eventSource.notify();
433
436
  setTimeout(() => {
434
- this._cachedPromise = null;
435
- this._eventSource.notify();
437
+ this.#cachedPromise = null;
438
+ this.#eventSource.notify();
436
439
  }, 5e3);
437
440
  }
438
441
  );
439
- this._cachedPromise = promise;
442
+ this.#cachedPromise = promise;
440
443
  return promise;
441
444
  }
442
445
  };
443
446
  var SinglePageResource = class {
447
+
448
+ #eventSource;
449
+ #fetchPage;
444
450
  constructor(fetchPage) {
445
- this._cachedPromise = null;
446
- this._fetchPage = fetchPage;
447
- this._eventSource = _core.makeEventSource.call(void 0, );
448
- this.observable = this._eventSource.observable;
451
+ this.#fetchPage = fetchPage;
452
+ this.#eventSource = _core.makeEventSource.call(void 0, );
453
+ this.observable = this.#eventSource.observable;
449
454
  autobind(this);
450
455
  }
451
456
  get() {
452
- const usable = this._cachedPromise;
457
+ const usable = this.#cachedPromise;
453
458
  if (usable === null || usable.status === "pending") {
454
459
  return ASYNC_LOADING;
455
460
  }
@@ -461,95 +466,187 @@ var SinglePageResource = class {
461
466
  data: void 0
462
467
  };
463
468
  }
469
+ #cachedPromise = null;
464
470
  waitUntilLoaded() {
465
- if (this._cachedPromise) {
466
- return this._cachedPromise;
471
+ if (this.#cachedPromise) {
472
+ return this.#cachedPromise;
467
473
  }
468
474
  const initialFetcher = _core.autoRetry.call(void 0,
469
- () => this._fetchPage(),
475
+ () => this.#fetchPage(),
470
476
  5,
471
477
  [5e3, 5e3, 1e4, 15e3]
472
478
  );
473
479
  const promise = usify(initialFetcher);
474
480
  promise.then(
475
- () => this._eventSource.notify(),
481
+ () => this.#eventSource.notify(),
476
482
  () => {
477
- this._eventSource.notify();
483
+ this.#eventSource.notify();
478
484
  setTimeout(() => {
479
- this._cachedPromise = null;
480
- this._eventSource.notify();
485
+ this.#cachedPromise = null;
486
+ this.#eventSource.notify();
481
487
  }, 5e3);
482
488
  }
483
489
  );
484
- this._cachedPromise = promise;
490
+ this.#cachedPromise = promise;
485
491
  return promise;
486
492
  }
487
493
  };
488
494
  var UmbrellaStore = class {
495
+ #client;
496
+ #syncSource;
497
+ //
498
+ // Internally, the UmbrellaStore keeps track of a few source signals that can
499
+ // be set and mutated individually. When any of those are mutated then the
500
+ // clean "external state" is recomputed.
501
+ //
502
+ // Mutate inputs... ...observe clean/consistent output!
503
+ //
504
+ // .-> Base ThreadDB ---------+ +----> Clean threads by ID (Part 1)
505
+ // / | |
506
+ // mutate ----> Base Notifications --+ | | +--> Clean notifications (Part 1)
507
+ // \ | | | | & notifications by ID
508
+ // | \ | | Apply | |
509
+ // | `-> OptimisticUpdates --+--+--> Optimistic --+-+--> Notification Settings (Part 2)
510
+ // \ | Updates |
511
+ // `------- etc etc ---------+ +--> History Versions (Part 3)
512
+ // ^
513
+ // |
514
+ // | ^ ^
515
+ // Signal | |
516
+ // or DerivedSignal DerivedSignals
517
+ // MutableSignal
518
+ //
519
+ //
520
+ // Input signals.
521
+ // (Can be mutated directly.)
522
+ //
523
+
524
+ // Exposes its signal under `.signal` prop
525
+
526
+
527
+
528
+
529
+
530
+ //
531
+ // Output signals.
532
+ // (Readonly, clean, consistent. With optimistic updates applied.)
533
+ //
534
+ // Note that the output of threadifications signal is the same as the ones for
535
+ // threads and notifications separately, but the threadifications signal will
536
+ // be updated whenever either of them change.
537
+ //
538
+ // TODO(vincent+nimesh) APIs like getRoomThreadsLoadingState should really also be modeled as output signals.
539
+ //
540
+
541
+ // Notifications
542
+ #notificationsLastRequestedAt = null;
543
+ // Keeps track of when we successfully requested an inbox notifications update for the last time. Will be `null` as long as the first successful fetch hasn't happened yet.
544
+ #notifications;
545
+ // Room Threads
546
+ #roomThreadsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
547
+ #roomThreads = /* @__PURE__ */ new Map();
548
+ // User Threads
549
+ #userThreadsLastRequestedAt = null;
550
+ #userThreads = /* @__PURE__ */ new Map();
551
+ // Room versions
552
+ #roomVersions = /* @__PURE__ */ new Map();
553
+ #roomVersionsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
554
+ // Room notification settings
555
+ #roomNotificationSettings = /* @__PURE__ */ new Map();
489
556
  constructor(client) {
490
- this._prevVersion = -1;
491
- this._prevState = null;
492
- this._stateCached = null;
493
- // Notifications
494
- this._notificationsLastRequestedAt = null;
495
- // Room Threads
496
- this._roomThreadsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
497
- this._roomThreads = /* @__PURE__ */ new Map();
498
- // User Threads
499
- this._userThreadsLastRequestedAt = null;
500
- this._userThreads = /* @__PURE__ */ new Map();
501
- // Room versions
502
- this._roomVersions = /* @__PURE__ */ new Map();
503
- this._roomVersionsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
504
- // Room notification settings
505
- this._roomNotificationSettings = /* @__PURE__ */ new Map();
506
- this._client = client[_core.kInternal].as();
507
- this._syncSource = this._client[_core.kInternal].createSyncSource();
557
+ this.#client = client[_core.kInternal].as();
558
+ this.#syncSource = this.#client[_core.kInternal].createSyncSource();
508
559
  const inboxFetcher = async (cursor) => {
509
- const result = await this._client.getInboxNotifications({ cursor });
560
+ const result = await this.#client.getInboxNotifications({ cursor });
510
561
  this.updateThreadsAndNotifications(
511
562
  result.threads,
512
563
  result.inboxNotifications
513
564
  );
514
- if (this._notificationsLastRequestedAt === null) {
515
- this._notificationsLastRequestedAt = result.requestedAt;
565
+ if (this.#notificationsLastRequestedAt === null) {
566
+ this.#notificationsLastRequestedAt = result.requestedAt;
516
567
  }
517
568
  const nextCursor = result.nextCursor;
518
569
  return nextCursor;
519
570
  };
520
- this._notifications = new PaginatedResource(inboxFetcher);
521
- this._notifications.observable.subscribe(
571
+ this.#notifications = new PaginatedResource(inboxFetcher);
572
+ this.#notifications.observable.subscribe(
522
573
  () => (
523
574
  // Note that the store itself does not change, but it's only vehicle at
524
575
  // the moment to trigger a re-render, so we'll do a no-op update here.
525
- this._store.set((store) => ({ ...store }))
576
+ this.invalidateEntireStore()
577
+ )
578
+ );
579
+ this.baseThreadsDB = new ThreadDB();
580
+ this.optimisticUpdates = new (0, _core.Signal)([]);
581
+ this.baseVersionsByRoomId = new (0, _core.Signal)({});
582
+ this.baseNotificationsById = new (0, _core.Signal)({});
583
+ this.baseSettingsByRoomId = new (0, _core.Signal)({});
584
+ this.permissionHintsByRoomId = new (0, _core.Signal)({});
585
+ const threadifications = _core.DerivedSignal.from(
586
+ this.baseThreadsDB.signal,
587
+ this.baseNotificationsById,
588
+ this.optimisticUpdates,
589
+ (ts, ns, updates) => applyOptimisticUpdates_forThreadifications(ts, ns, updates)
590
+ );
591
+ const threads = _core.DerivedSignal.from(threadifications, (s) => ({
592
+ threadsDB: s.threadsDB
593
+ }));
594
+ const notifications = _core.DerivedSignal.from(threadifications, (s) => ({
595
+ sortedNotifications: s.sortedNotifications,
596
+ notificationsById: s.notificationsById
597
+ }));
598
+ const settingsByRoomId = _core.DerivedSignal.from(
599
+ this.baseSettingsByRoomId,
600
+ this.optimisticUpdates,
601
+ (settings, updates) => applyOptimisticUpdates_forSettings(settings, updates)
602
+ );
603
+ const versionsByRoomId = _core.DerivedSignal.from(
604
+ this.baseVersionsByRoomId,
605
+ (hv) => hv
606
+ );
607
+ this.outputs = {
608
+ threadifications,
609
+ threads,
610
+ notifications,
611
+ settingsByRoomId,
612
+ versionsByRoomId
613
+ };
614
+ this.optimisticUpdates.subscribe(
615
+ () => this.#syncSource.setSyncStatus(
616
+ this.optimisticUpdates.get().length > 0 ? "synchronizing" : "synchronized"
526
617
  )
527
618
  );
528
- this._rawThreadsDB = new ThreadDB();
529
- this._store = _core.createStore.call(void 0, {
530
- optimisticUpdates: [],
531
- permissionsByRoom: {},
532
- notificationsById: {},
533
- settingsByRoomId: {},
534
- versionsByRoomId: {}
535
- });
536
619
  autobind(this);
537
620
  }
538
- get() {
539
- const rawState = this._store.get();
540
- if (this._prevVersion !== this._rawThreadsDB.version || // Note: Version check is only needed temporarily, until we can get rid of the Zustand-like update model
541
- this._prevState !== rawState || this._stateCached === null) {
542
- this._stateCached = internalToExternalState(rawState, this._rawThreadsDB);
543
- this._prevState = rawState;
544
- this._prevVersion = this._rawThreadsDB.version;
545
- }
546
- return this._stateCached;
621
+ get1_both() {
622
+ return this.outputs.threadifications.get();
623
+ }
624
+ subscribe1_both(callback) {
625
+ return this.outputs.threadifications.subscribe(callback);
547
626
  }
548
- batch(callback) {
549
- return this._store.batch(callback);
627
+ get1_threads() {
628
+ return this.outputs.threads.get();
550
629
  }
551
- getFullState() {
552
- return this.get();
630
+ subscribe1_threads(callback) {
631
+ return this.outputs.threads.subscribe(callback);
632
+ }
633
+ get1_notifications() {
634
+ return this.outputs.notifications.get();
635
+ }
636
+ subscribe1_notifications(callback) {
637
+ return this.outputs.notifications.subscribe(callback);
638
+ }
639
+ get2() {
640
+ return this.outputs.settingsByRoomId.get();
641
+ }
642
+ subscribe2(callback) {
643
+ return this.outputs.settingsByRoomId.subscribe(callback);
644
+ }
645
+ get3() {
646
+ return this.outputs.versionsByRoomId.get();
647
+ }
648
+ subscribe3(callback) {
649
+ return this.outputs.versionsByRoomId.subscribe(callback);
553
650
  }
554
651
  /**
555
652
  * Returns the async result of the given query and room id. If the query is success,
@@ -558,7 +655,7 @@ var UmbrellaStore = class {
558
655
  */
559
656
  getRoomThreadsLoadingState(roomId, query) {
560
657
  const queryKey = makeRoomThreadsQueryKey(roomId, query);
561
- const paginatedResource = this._roomThreads.get(queryKey);
658
+ const paginatedResource = this.#roomThreads.get(queryKey);
562
659
  if (paginatedResource === void 0) {
563
660
  return ASYNC_LOADING;
564
661
  }
@@ -566,7 +663,7 @@ var UmbrellaStore = class {
566
663
  if (asyncResult.isLoading || asyncResult.error) {
567
664
  return asyncResult;
568
665
  }
569
- const threads = this.getFullState().threadsDB.findMany(
666
+ const threads = this.get1_threads().threadsDB.findMany(
570
667
  roomId,
571
668
  _nullishCoalesce(query, () => ( {})),
572
669
  "asc"
@@ -583,7 +680,7 @@ var UmbrellaStore = class {
583
680
  }
584
681
  getUserThreadsLoadingState(query) {
585
682
  const queryKey = makeUserThreadsQueryKey(query);
586
- const paginatedResource = this._userThreads.get(queryKey);
683
+ const paginatedResource = this.#userThreads.get(queryKey);
587
684
  if (paginatedResource === void 0) {
588
685
  return ASYNC_LOADING;
589
686
  }
@@ -591,7 +688,7 @@ var UmbrellaStore = class {
591
688
  if (asyncResult.isLoading || asyncResult.error) {
592
689
  return asyncResult;
593
690
  }
594
- const threads = this.getFullState().threadsDB.findMany(
691
+ const threads = this.get1_threads().threadsDB.findMany(
595
692
  void 0,
596
693
  // Do _not_ filter by roomId
597
694
  _nullishCoalesce(query, () => ( {})),
@@ -609,14 +706,14 @@ var UmbrellaStore = class {
609
706
  }
610
707
  // NOTE: This will read the async result, but WILL NOT start loading at the moment!
611
708
  getInboxNotificationsLoadingState() {
612
- const asyncResult = this._notifications.get();
709
+ const asyncResult = this.#notifications.get();
613
710
  if (asyncResult.isLoading || asyncResult.error) {
614
711
  return asyncResult;
615
712
  }
616
713
  const page = asyncResult.data;
617
714
  return {
618
715
  isLoading: false,
619
- inboxNotifications: this.getFullState().cleanedNotifications,
716
+ inboxNotifications: this.get1_notifications().sortedNotifications,
620
717
  hasFetchedAll: page.hasFetchedAll,
621
718
  isFetchingMore: page.isFetchingMore,
622
719
  fetchMoreError: page.fetchMoreError,
@@ -624,9 +721,10 @@ var UmbrellaStore = class {
624
721
  };
625
722
  }
626
723
  // NOTE: This will read the async result, but WILL NOT start loading at the moment!
724
+ // TODO(vincent+nimesh) This should really be a derived Signal!
627
725
  getNotificationSettingsLoadingState(roomId) {
628
726
  const queryKey = makeNotificationSettingsQueryKey(roomId);
629
- const resource = this._roomNotificationSettings.get(queryKey);
727
+ const resource = this.#roomNotificationSettings.get(queryKey);
630
728
  if (resource === void 0) {
631
729
  return ASYNC_LOADING;
632
730
  }
@@ -636,12 +734,12 @@ var UmbrellaStore = class {
636
734
  }
637
735
  return {
638
736
  isLoading: false,
639
- settings: _core.nn.call(void 0, this.get().settingsByRoomId[roomId])
737
+ settings: _core.nn.call(void 0, this.get2()[roomId])
640
738
  };
641
739
  }
642
740
  getRoomVersionsLoadingState(roomId) {
643
741
  const queryKey = makeVersionsQueryKey(roomId);
644
- const resource = this._roomVersions.get(queryKey);
742
+ const resource = this.#roomVersions.get(queryKey);
645
743
  if (resource === void 0) {
646
744
  return ASYNC_LOADING;
647
745
  }
@@ -651,70 +749,53 @@ var UmbrellaStore = class {
651
749
  }
652
750
  return {
653
751
  isLoading: false,
654
- versions: Object.values(_nullishCoalesce(this.get().versionsByRoomId[roomId], () => ( {})))
752
+ versions: Object.values(_nullishCoalesce(this.get3()[roomId], () => ( {})))
655
753
  };
656
754
  }
657
- subscribe(callback) {
658
- return this._store.subscribe(callback);
659
- }
660
- _getPermissions(roomId) {
661
- return this._store.get().permissionsByRoom[roomId];
662
- }
663
755
  // Direct low-level cache mutations ------------------------------------------------- {{{
664
- mutateThreadsDB(mutate) {
665
- const db = this._rawThreadsDB;
666
- const old = db.version;
667
- mutate(db);
668
- if (old !== db.version) {
669
- this._store.set((state) => ({ ...state }));
670
- }
671
- }
672
- updateInboxNotificationsCache(mapFn) {
673
- this._store.set((state) => {
674
- const inboxNotifications = mapFn(state.notificationsById);
675
- return inboxNotifications !== state.notificationsById ? { ...state, notificationsById: inboxNotifications } : state;
756
+ #mutateThreadsDB(mutate) {
757
+ _core.batch.call(void 0, () => {
758
+ mutate(this.baseThreadsDB);
676
759
  });
677
760
  }
678
- setNotificationSettings(roomId, settings) {
679
- this._store.set((state) => ({
761
+ #updateInboxNotificationsCache(mapFn) {
762
+ this.baseNotificationsById.set((prev) => mapFn(prev));
763
+ }
764
+ #setNotificationSettings(roomId, settings) {
765
+ this.baseSettingsByRoomId.set((state) => ({
680
766
  ...state,
681
- settingsByRoomId: {
682
- ...state.settingsByRoomId,
683
- [roomId]: settings
684
- }
767
+ [roomId]: settings
685
768
  }));
686
769
  }
687
- updateRoomVersions(roomId, versions) {
688
- this._store.set((state) => {
689
- const versionsById = Object.fromEntries(
690
- versions.map((version2) => [version2.id, version2])
691
- );
770
+ #updateRoomVersions(roomId, versions) {
771
+ this.baseVersionsByRoomId.set((prev) => {
772
+ const newVersions = { ...prev[roomId] };
773
+ for (const version2 of versions) {
774
+ newVersions[version2.id] = version2;
775
+ }
692
776
  return {
693
- ...state,
694
- versionsByRoomId: {
695
- ...state.versionsByRoomId,
696
- [roomId]: {
697
- // Merge with existing versions for the room, or start with an empty object
698
- ..._nullishCoalesce(state.versionsByRoomId[roomId], () => ( {})),
699
- ...versionsById
700
- }
701
- }
777
+ ...prev,
778
+ [roomId]: newVersions
702
779
  };
703
780
  });
704
781
  }
705
- updateOptimisticUpdatesCache(mapFn) {
706
- this._store.set((state) => {
707
- const optimisticUpdates = mapFn(state.optimisticUpdates);
708
- this._syncSource.setSyncStatus(
709
- optimisticUpdates.length > 0 ? "synchronizing" : "synchronized"
710
- );
711
- return { ...state, optimisticUpdates };
712
- });
782
+ #updateOptimisticUpdatesCache(mapFn) {
783
+ this.optimisticUpdates.set(mapFn);
713
784
  }
714
785
  // ---------------------------------------------------------------------------------- }}}
715
786
  /** @internal - Only call this method from unit tests. */
716
- force_set(callback) {
717
- return this._store.set(callback);
787
+ force_set_versions(callback) {
788
+ _core.batch.call(void 0, () => {
789
+ this.baseVersionsByRoomId.set(callback);
790
+ this.invalidateEntireStore();
791
+ });
792
+ }
793
+ /** @internal - Only call this method from unit tests. */
794
+ force_set_notifications(callback) {
795
+ _core.batch.call(void 0, () => {
796
+ this.baseNotificationsById.set(callback);
797
+ this.invalidateEntireStore();
798
+ });
718
799
  }
719
800
  /**
720
801
  * Updates an existing inbox notification with a new value, replacing the
@@ -724,18 +805,17 @@ var UmbrellaStore = class {
724
805
  * the cache.
725
806
  */
726
807
  updateInboxNotification(inboxNotificationId, optimisticUpdateId, callback) {
727
- this._store.batch(() => {
808
+ _core.batch.call(void 0, () => {
728
809
  this.removeOptimisticUpdate(optimisticUpdateId);
729
- this.updateInboxNotificationsCache((cache) => {
810
+ this.#updateInboxNotificationsCache((cache) => {
730
811
  const existing = cache[inboxNotificationId];
731
812
  if (!existing) {
732
813
  return cache;
733
814
  }
734
- const inboxNotifications = {
815
+ return {
735
816
  ...cache,
736
817
  [inboxNotificationId]: callback(existing)
737
818
  };
738
- return inboxNotifications;
739
819
  });
740
820
  });
741
821
  }
@@ -744,9 +824,9 @@ var UmbrellaStore = class {
744
824
  * them, replacing the corresponding optimistic update.
745
825
  */
746
826
  updateAllInboxNotifications(optimisticUpdateId, mapFn) {
747
- this._store.batch(() => {
827
+ _core.batch.call(void 0, () => {
748
828
  this.removeOptimisticUpdate(optimisticUpdateId);
749
- this.updateInboxNotificationsCache((cache) => _core.mapValues.call(void 0, cache, mapFn));
829
+ this.#updateInboxNotificationsCache((cache) => _core.mapValues.call(void 0, cache, mapFn));
750
830
  });
751
831
  }
752
832
  /**
@@ -754,9 +834,9 @@ var UmbrellaStore = class {
754
834
  * optimistic update.
755
835
  */
756
836
  deleteInboxNotification(inboxNotificationId, optimisticUpdateId) {
757
- this._store.batch(() => {
837
+ _core.batch.call(void 0, () => {
758
838
  this.removeOptimisticUpdate(optimisticUpdateId);
759
- this.updateInboxNotificationsCache((cache) => {
839
+ this.#updateInboxNotificationsCache((cache) => {
760
840
  const { [inboxNotificationId]: removed, ...newCache } = cache;
761
841
  return removed === void 0 ? cache : newCache;
762
842
  });
@@ -767,18 +847,18 @@ var UmbrellaStore = class {
767
847
  * update.
768
848
  */
769
849
  deleteAllInboxNotifications(optimisticUpdateId) {
770
- this._store.batch(() => {
850
+ _core.batch.call(void 0, () => {
771
851
  this.removeOptimisticUpdate(optimisticUpdateId);
772
- this.updateInboxNotificationsCache(() => ({}));
852
+ this.#updateInboxNotificationsCache(() => ({}));
773
853
  });
774
854
  }
775
855
  /**
776
856
  * Creates an new thread, replacing the corresponding optimistic update.
777
857
  */
778
858
  createThread(optimisticUpdateId, thread) {
779
- this._store.batch(() => {
859
+ _core.batch.call(void 0, () => {
780
860
  this.removeOptimisticUpdate(optimisticUpdateId);
781
- this.mutateThreadsDB((db) => db.upsert(thread));
861
+ this.#mutateThreadsDB((db) => db.upsert(thread));
782
862
  });
783
863
  }
784
864
  /**
@@ -791,12 +871,12 @@ var UmbrellaStore = class {
791
871
  * - The thread ID in the cache was updated more recently than the optimistic
792
872
  * update's timestamp (if given)
793
873
  */
794
- updateThread(threadId, optimisticUpdateId, callback, updatedAt) {
795
- this._store.batch(() => {
874
+ #updateThread(threadId, optimisticUpdateId, callback, updatedAt) {
875
+ _core.batch.call(void 0, () => {
796
876
  if (optimisticUpdateId !== null) {
797
877
  this.removeOptimisticUpdate(optimisticUpdateId);
798
878
  }
799
- this.mutateThreadsDB((db) => {
879
+ this.#mutateThreadsDB((db) => {
800
880
  const existing = db.get(threadId);
801
881
  if (!existing) return;
802
882
  if (!!updatedAt && existing.updatedAt > updatedAt) return;
@@ -805,7 +885,7 @@ var UmbrellaStore = class {
805
885
  });
806
886
  }
807
887
  patchThread(threadId, optimisticUpdateId, patch, updatedAt) {
808
- return this.updateThread(
888
+ return this.#updateThread(
809
889
  threadId,
810
890
  optimisticUpdateId,
811
891
  (thread) => ({ ...thread, ..._core.compactObject.call(void 0, patch) }),
@@ -813,7 +893,7 @@ var UmbrellaStore = class {
813
893
  );
814
894
  }
815
895
  addReaction(threadId, optimisticUpdateId, commentId, reaction, createdAt) {
816
- this.updateThread(
896
+ this.#updateThread(
817
897
  threadId,
818
898
  optimisticUpdateId,
819
899
  (thread) => applyAddReaction(thread, commentId, reaction),
@@ -821,7 +901,7 @@ var UmbrellaStore = class {
821
901
  );
822
902
  }
823
903
  removeReaction(threadId, optimisticUpdateId, commentId, emoji, userId, removedAt) {
824
- this.updateThread(
904
+ this.#updateThread(
825
905
  threadId,
826
906
  optimisticUpdateId,
827
907
  (thread) => applyRemoveReaction(thread, commentId, emoji, userId, removedAt),
@@ -837,7 +917,7 @@ var UmbrellaStore = class {
837
917
  * - The thread ID was already deleted from the cache
838
918
  */
839
919
  deleteThread(threadId, optimisticUpdateId) {
840
- return this.updateThread(
920
+ return this.#updateThread(
841
921
  threadId,
842
922
  optimisticUpdateId,
843
923
  // A deletion is actually an update of the deletedAt property internally
@@ -849,16 +929,16 @@ var UmbrellaStore = class {
849
929
  * updated correctly, replacing the corresponding optimistic update.
850
930
  */
851
931
  createComment(newComment, optimisticUpdateId) {
852
- this._store.batch(() => {
932
+ _core.batch.call(void 0, () => {
853
933
  this.removeOptimisticUpdate(optimisticUpdateId);
854
- const existingThread = this._rawThreadsDB.get(newComment.threadId);
934
+ const existingThread = this.baseThreadsDB.get(newComment.threadId);
855
935
  if (!existingThread) {
856
936
  return;
857
937
  }
858
- this.mutateThreadsDB(
938
+ this.#mutateThreadsDB(
859
939
  (db) => db.upsert(applyUpsertComment(existingThread, newComment))
860
940
  );
861
- this.updateInboxNotificationsCache((cache) => {
941
+ this.#updateInboxNotificationsCache((cache) => {
862
942
  const existingNotification = Object.values(cache).find(
863
943
  (notification) => notification.kind === "thread" && notification.threadId === newComment.threadId
864
944
  );
@@ -877,14 +957,14 @@ var UmbrellaStore = class {
877
957
  });
878
958
  }
879
959
  editComment(threadId, optimisticUpdateId, editedComment) {
880
- return this.updateThread(
960
+ return this.#updateThread(
881
961
  threadId,
882
962
  optimisticUpdateId,
883
963
  (thread) => applyUpsertComment(thread, editedComment)
884
964
  );
885
965
  }
886
966
  deleteComment(threadId, optimisticUpdateId, commentId, deletedAt) {
887
- return this.updateThread(
967
+ return this.#updateThread(
888
968
  threadId,
889
969
  optimisticUpdateId,
890
970
  (thread) => applyDeleteComment(thread, commentId, deletedAt),
@@ -892,10 +972,10 @@ var UmbrellaStore = class {
892
972
  );
893
973
  }
894
974
  updateThreadAndNotification(thread, inboxNotification) {
895
- this._store.batch(() => {
896
- this.mutateThreadsDB((db) => db.upsertIfNewer(thread));
975
+ _core.batch.call(void 0, () => {
976
+ this.#mutateThreadsDB((db) => db.upsertIfNewer(thread));
897
977
  if (inboxNotification !== void 0) {
898
- this.updateInboxNotificationsCache((cache) => ({
978
+ this.#updateInboxNotificationsCache((cache) => ({
899
979
  ...cache,
900
980
  [inboxNotification.id]: inboxNotification
901
981
  }));
@@ -903,11 +983,11 @@ var UmbrellaStore = class {
903
983
  });
904
984
  }
905
985
  updateThreadsAndNotifications(threads, inboxNotifications, deletedThreads = [], deletedInboxNotifications = []) {
906
- this._store.batch(() => {
907
- this.mutateThreadsDB(
986
+ _core.batch.call(void 0, () => {
987
+ this.#mutateThreadsDB(
908
988
  (db) => applyThreadDeltaUpdates(db, { newThreads: threads, deletedThreads })
909
989
  );
910
- this.updateInboxNotificationsCache(
990
+ this.#updateInboxNotificationsCache(
911
991
  (cache) => applyNotificationsUpdates(cache, {
912
992
  newInboxNotifications: inboxNotifications,
913
993
  deletedNotifications: deletedInboxNotifications
@@ -920,33 +1000,33 @@ var UmbrellaStore = class {
920
1000
  * replacing the corresponding optimistic update.
921
1001
  */
922
1002
  updateRoomNotificationSettings_confirmOptimisticUpdate(roomId, optimisticUpdateId, settings) {
923
- this._store.batch(() => {
1003
+ _core.batch.call(void 0, () => {
924
1004
  this.removeOptimisticUpdate(optimisticUpdateId);
925
- this.setNotificationSettings(roomId, settings);
1005
+ this.#setNotificationSettings(roomId, settings);
926
1006
  });
927
1007
  }
928
1008
  addOptimisticUpdate(optimisticUpdate) {
929
1009
  const id = _core.nanoid.call(void 0, );
930
1010
  const newUpdate = { ...optimisticUpdate, id };
931
- this.updateOptimisticUpdatesCache((cache) => [...cache, newUpdate]);
1011
+ this.#updateOptimisticUpdatesCache((cache) => [...cache, newUpdate]);
932
1012
  return id;
933
1013
  }
934
1014
  removeOptimisticUpdate(optimisticUpdateId) {
935
- this.updateOptimisticUpdatesCache(
1015
+ this.#updateOptimisticUpdatesCache(
936
1016
  (cache) => cache.filter((ou) => ou.id !== optimisticUpdateId)
937
1017
  );
938
1018
  }
939
1019
  async fetchNotificationsDeltaUpdate(signal) {
940
- const lastRequestedAt = this._notificationsLastRequestedAt;
1020
+ const lastRequestedAt = this.#notificationsLastRequestedAt;
941
1021
  if (lastRequestedAt === null) {
942
1022
  return;
943
1023
  }
944
- const result = await this._client.getInboxNotificationsSince({
1024
+ const result = await this.#client.getInboxNotificationsSince({
945
1025
  since: lastRequestedAt,
946
1026
  signal
947
1027
  });
948
1028
  if (lastRequestedAt < result.requestedAt) {
949
- this._notificationsLastRequestedAt = result.requestedAt;
1029
+ this.#notificationsLastRequestedAt = result.requestedAt;
950
1030
  }
951
1031
  this.updateThreadsAndNotifications(
952
1032
  result.threads.updated,
@@ -956,25 +1036,24 @@ var UmbrellaStore = class {
956
1036
  );
957
1037
  }
958
1038
  waitUntilNotificationsLoaded() {
959
- return this._notifications.waitUntilLoaded();
960
- }
961
- updateRoomPermissions(permissions) {
962
- const permissionsByRoom = { ...this._store.get().permissionsByRoom };
963
- Object.entries(permissions).forEach(([roomId, newPermissions]) => {
964
- const existingPermissions = _nullishCoalesce(permissionsByRoom[roomId], () => ( /* @__PURE__ */ new Set()));
965
- newPermissions.forEach(
966
- (permission) => existingPermissions.add(permission)
967
- );
968
- permissionsByRoom[roomId] = existingPermissions;
1039
+ return this.#notifications.waitUntilLoaded();
1040
+ }
1041
+ #updatePermissionHints(newHints) {
1042
+ this.permissionHintsByRoomId.set((prev) => {
1043
+ const permissionsByRoom = { ...prev };
1044
+ for (const [roomId, newPermissions] of Object.entries(newHints)) {
1045
+ const existing = _nullishCoalesce(permissionsByRoom[roomId], () => ( /* @__PURE__ */ new Set()));
1046
+ for (const permission of newPermissions) {
1047
+ existing.add(permission);
1048
+ }
1049
+ permissionsByRoom[roomId] = existing;
1050
+ }
1051
+ return permissionsByRoom;
969
1052
  });
970
- this._store.set((state) => ({
971
- ...state,
972
- permissionsByRoom
973
- }));
974
1053
  }
975
1054
  waitUntilRoomThreadsLoaded(roomId, query) {
976
1055
  const threadsFetcher = async (cursor) => {
977
- const result = await this._client[_core.kInternal].httpClient.getThreads({
1056
+ const result = await this.#client[_core.kInternal].httpClient.getThreads({
978
1057
  roomId,
979
1058
  cursor,
980
1059
  query
@@ -983,15 +1062,15 @@ var UmbrellaStore = class {
983
1062
  result.threads,
984
1063
  result.inboxNotifications
985
1064
  );
986
- this.updateRoomPermissions(result.permissionHints);
987
- const lastRequestedAt = this._roomThreadsLastRequestedAtByRoom.get(roomId);
1065
+ this.#updatePermissionHints(result.permissionHints);
1066
+ const lastRequestedAt = this.#roomThreadsLastRequestedAtByRoom.get(roomId);
988
1067
  if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
989
- this._roomThreadsLastRequestedAtByRoom.set(roomId, result.requestedAt);
1068
+ this.#roomThreadsLastRequestedAtByRoom.set(roomId, result.requestedAt);
990
1069
  }
991
1070
  return result.nextCursor;
992
1071
  };
993
1072
  const queryKey = makeRoomThreadsQueryKey(roomId, query);
994
- let paginatedResource = this._roomThreads.get(queryKey);
1073
+ let paginatedResource = this.#roomThreads.get(queryKey);
995
1074
  if (paginatedResource === void 0) {
996
1075
  paginatedResource = new PaginatedResource(threadsFetcher);
997
1076
  }
@@ -999,18 +1078,18 @@ var UmbrellaStore = class {
999
1078
  () => (
1000
1079
  // Note that the store itself does not change, but it's only vehicle at
1001
1080
  // the moment to trigger a re-render, so we'll do a no-op update here.
1002
- this._store.set((store) => ({ ...store }))
1081
+ this.invalidateEntireStore()
1003
1082
  )
1004
1083
  );
1005
- this._roomThreads.set(queryKey, paginatedResource);
1084
+ this.#roomThreads.set(queryKey, paginatedResource);
1006
1085
  return paginatedResource.waitUntilLoaded();
1007
1086
  }
1008
1087
  async fetchRoomThreadsDeltaUpdate(roomId, signal) {
1009
- const lastRequestedAt = this._roomThreadsLastRequestedAtByRoom.get(roomId);
1088
+ const lastRequestedAt = this.#roomThreadsLastRequestedAtByRoom.get(roomId);
1010
1089
  if (lastRequestedAt === void 0) {
1011
1090
  return;
1012
1091
  }
1013
- const updates = await this._client[_core.kInternal].httpClient.getThreadsSince({
1092
+ const updates = await this.#client[_core.kInternal].httpClient.getThreadsSince({
1014
1093
  roomId,
1015
1094
  since: lastRequestedAt,
1016
1095
  signal
@@ -1021,15 +1100,15 @@ var UmbrellaStore = class {
1021
1100
  updates.threads.deleted,
1022
1101
  updates.inboxNotifications.deleted
1023
1102
  );
1024
- this.updateRoomPermissions(updates.permissionHints);
1103
+ this.#updatePermissionHints(updates.permissionHints);
1025
1104
  if (lastRequestedAt < updates.requestedAt) {
1026
- this._roomThreadsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
1105
+ this.#roomThreadsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
1027
1106
  }
1028
1107
  }
1029
1108
  waitUntilUserThreadsLoaded(query) {
1030
1109
  const queryKey = makeUserThreadsQueryKey(query);
1031
1110
  const threadsFetcher = async (cursor) => {
1032
- const result = await this._client[_core.kInternal].httpClient.getUserThreads_experimental({
1111
+ const result = await this.#client[_core.kInternal].httpClient.getUserThreads_experimental({
1033
1112
  cursor,
1034
1113
  query
1035
1114
  });
@@ -1037,13 +1116,13 @@ var UmbrellaStore = class {
1037
1116
  result.threads,
1038
1117
  result.inboxNotifications
1039
1118
  );
1040
- this.updateRoomPermissions(result.permissionHints);
1041
- if (this._userThreadsLastRequestedAt === null) {
1042
- this._userThreadsLastRequestedAt = result.requestedAt;
1119
+ this.#updatePermissionHints(result.permissionHints);
1120
+ if (this.#userThreadsLastRequestedAt === null) {
1121
+ this.#userThreadsLastRequestedAt = result.requestedAt;
1043
1122
  }
1044
1123
  return result.nextCursor;
1045
1124
  };
1046
- let paginatedResource = this._userThreads.get(queryKey);
1125
+ let paginatedResource = this.#userThreads.get(queryKey);
1047
1126
  if (paginatedResource === void 0) {
1048
1127
  paginatedResource = new PaginatedResource(threadsFetcher);
1049
1128
  }
@@ -1051,23 +1130,34 @@ var UmbrellaStore = class {
1051
1130
  () => (
1052
1131
  // Note that the store itself does not change, but it's only vehicle at
1053
1132
  // the moment to trigger a re-render, so we'll do a no-op update here.
1054
- this._store.set((store) => ({ ...store }))
1133
+ this.invalidateEntireStore()
1055
1134
  )
1056
1135
  );
1057
- this._userThreads.set(queryKey, paginatedResource);
1136
+ this.#userThreads.set(queryKey, paginatedResource);
1058
1137
  return paginatedResource.waitUntilLoaded();
1059
1138
  }
1139
+ // TODO(vincent+nimesh) We should really be going over all call sites, and replace this call
1140
+ // with a more specific invalidation!
1141
+ invalidateEntireStore() {
1142
+ _core.batch.call(void 0, () => {
1143
+ this.baseVersionsByRoomId.set((store) => ({ ...store }));
1144
+ this.baseNotificationsById.set((store) => ({ ...store }));
1145
+ this.optimisticUpdates.set((store) => [...store]);
1146
+ this.permissionHintsByRoomId.set((store) => ({ ...store }));
1147
+ this.baseSettingsByRoomId.set((store) => ({ ...store }));
1148
+ });
1149
+ }
1060
1150
  async fetchUserThreadsDeltaUpdate(signal) {
1061
- const lastRequestedAt = this._userThreadsLastRequestedAt;
1151
+ const lastRequestedAt = this.#userThreadsLastRequestedAt;
1062
1152
  if (lastRequestedAt === null) {
1063
1153
  return;
1064
1154
  }
1065
- const result = await this._client[_core.kInternal].httpClient.getUserThreadsSince_experimental({
1155
+ const result = await this.#client[_core.kInternal].httpClient.getUserThreadsSince_experimental({
1066
1156
  since: lastRequestedAt,
1067
1157
  signal
1068
1158
  });
1069
1159
  if (lastRequestedAt < result.requestedAt) {
1070
- this._notificationsLastRequestedAt = result.requestedAt;
1160
+ this.#notificationsLastRequestedAt = result.requestedAt;
1071
1161
  }
1072
1162
  this.updateThreadsAndNotifications(
1073
1163
  result.threads.updated,
@@ -1075,14 +1165,14 @@ var UmbrellaStore = class {
1075
1165
  result.threads.deleted,
1076
1166
  result.inboxNotifications.deleted
1077
1167
  );
1078
- this.updateRoomPermissions(result.permissionHints);
1168
+ this.#updatePermissionHints(result.permissionHints);
1079
1169
  }
1080
1170
  waitUntilRoomVersionsLoaded(roomId) {
1081
1171
  const queryKey = makeVersionsQueryKey(roomId);
1082
- let resource = this._roomVersions.get(queryKey);
1172
+ let resource = this.#roomVersions.get(queryKey);
1083
1173
  if (resource === void 0) {
1084
1174
  const versionsFetcher = async () => {
1085
- const room = this._client.getRoom(roomId);
1175
+ const room = this.#client.getRoom(roomId);
1086
1176
  if (room === null) {
1087
1177
  throw new (0, _core.HttpError)(
1088
1178
  `Room '${roomId}' is not available on client`,
@@ -1090,10 +1180,10 @@ var UmbrellaStore = class {
1090
1180
  );
1091
1181
  }
1092
1182
  const result = await room[_core.kInternal].listTextVersions();
1093
- this.updateRoomVersions(roomId, result.versions);
1094
- const lastRequestedAt = this._roomVersionsLastRequestedAtByRoom.get(roomId);
1183
+ this.#updateRoomVersions(roomId, result.versions);
1184
+ const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
1095
1185
  if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
1096
- this._roomVersionsLastRequestedAtByRoom.set(
1186
+ this.#roomVersionsLastRequestedAtByRoom.set(
1097
1187
  roomId,
1098
1188
  result.requestedAt
1099
1189
  );
@@ -1105,36 +1195,36 @@ var UmbrellaStore = class {
1105
1195
  () => (
1106
1196
  // Note that the store itself does not change, but it's only vehicle at
1107
1197
  // the moment to trigger a re-render, so we'll do a no-op update here.
1108
- this._store.set((store) => ({ ...store }))
1198
+ this.invalidateEntireStore()
1109
1199
  )
1110
1200
  );
1111
- this._roomVersions.set(queryKey, resource);
1201
+ this.#roomVersions.set(queryKey, resource);
1112
1202
  return resource.waitUntilLoaded();
1113
1203
  }
1114
1204
  async fetchRoomVersionsDeltaUpdate(roomId, signal) {
1115
- const lastRequestedAt = this._roomVersionsLastRequestedAtByRoom.get(roomId);
1205
+ const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
1116
1206
  if (lastRequestedAt === void 0) {
1117
1207
  return;
1118
1208
  }
1119
1209
  const room = _core.nn.call(void 0,
1120
- this._client.getRoom(roomId),
1210
+ this.#client.getRoom(roomId),
1121
1211
  `Room with id ${roomId} is not available on client`
1122
1212
  );
1123
1213
  const updates = await room[_core.kInternal].listTextVersionsSince({
1124
1214
  since: lastRequestedAt,
1125
1215
  signal
1126
1216
  });
1127
- this.updateRoomVersions(roomId, updates.versions);
1217
+ this.#updateRoomVersions(roomId, updates.versions);
1128
1218
  if (lastRequestedAt < updates.requestedAt) {
1129
- this._roomVersionsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
1219
+ this.#roomVersionsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
1130
1220
  }
1131
1221
  }
1132
1222
  waitUntilRoomNotificationSettingsLoaded(roomId) {
1133
1223
  const queryKey = makeNotificationSettingsQueryKey(roomId);
1134
- let resource = this._roomNotificationSettings.get(queryKey);
1224
+ let resource = this.#roomNotificationSettings.get(queryKey);
1135
1225
  if (resource === void 0) {
1136
1226
  const notificationSettingsFetcher = async () => {
1137
- const room = this._client.getRoom(roomId);
1227
+ const room = this.#client.getRoom(roomId);
1138
1228
  if (room === null) {
1139
1229
  throw new (0, _core.HttpError)(
1140
1230
  `Room '${roomId}' is not available on client`,
@@ -1142,7 +1232,7 @@ var UmbrellaStore = class {
1142
1232
  );
1143
1233
  }
1144
1234
  const result = await room.getNotificationSettings();
1145
- this.setNotificationSettings(roomId, result);
1235
+ this.#setNotificationSettings(roomId, result);
1146
1236
  };
1147
1237
  resource = new SinglePageResource(notificationSettingsFetcher);
1148
1238
  }
@@ -1150,28 +1240,25 @@ var UmbrellaStore = class {
1150
1240
  () => (
1151
1241
  // Note that the store itself does not change, but it's only vehicle at
1152
1242
  // the moment to trigger a re-render, so we'll do a no-op update here.
1153
- this._store.set((store) => ({ ...store }))
1243
+ this.invalidateEntireStore()
1154
1244
  )
1155
1245
  );
1156
- this._roomNotificationSettings.set(queryKey, resource);
1246
+ this.#roomNotificationSettings.set(queryKey, resource);
1157
1247
  return resource.waitUntilLoaded();
1158
1248
  }
1159
1249
  async refreshRoomNotificationSettings(roomId, signal) {
1160
1250
  const room = _core.nn.call(void 0,
1161
- this._client.getRoom(roomId),
1251
+ this.#client.getRoom(roomId),
1162
1252
  `Room with id ${roomId} is not available on client`
1163
1253
  );
1164
1254
  const result = await room.getNotificationSettings({ signal });
1165
- this.setNotificationSettings(roomId, result);
1255
+ this.#setNotificationSettings(roomId, result);
1166
1256
  }
1167
1257
  };
1168
- function internalToExternalState(state, rawThreadsDB) {
1169
- const threadsDB = rawThreadsDB.clone();
1170
- const computed = {
1171
- notificationsById: { ...state.notificationsById },
1172
- settingsByRoomId: { ...state.settingsByRoomId }
1173
- };
1174
- for (const optimisticUpdate of state.optimisticUpdates) {
1258
+ function applyOptimisticUpdates_forThreadifications(baseThreadsDB, rawNotificationsById, optimisticUpdates) {
1259
+ const threadsDB = baseThreadsDB.clone();
1260
+ let notificationsById = { ...rawNotificationsById };
1261
+ for (const optimisticUpdate of optimisticUpdates) {
1175
1262
  switch (optimisticUpdate.type) {
1176
1263
  case "create-thread": {
1177
1264
  threadsDB.upsert(optimisticUpdate.thread);
@@ -1209,15 +1296,13 @@ function internalToExternalState(state, rawThreadsDB) {
1209
1296
  const thread = threadsDB.get(optimisticUpdate.comment.threadId);
1210
1297
  if (thread === void 0) break;
1211
1298
  threadsDB.upsert(applyUpsertComment(thread, optimisticUpdate.comment));
1212
- const inboxNotification = Object.values(
1213
- computed.notificationsById
1214
- ).find(
1299
+ const inboxNotification = Object.values(notificationsById).find(
1215
1300
  (notification) => notification.kind === "thread" && notification.threadId === thread.id
1216
1301
  );
1217
1302
  if (inboxNotification === void 0) {
1218
1303
  break;
1219
1304
  }
1220
- computed.notificationsById[inboxNotification.id] = {
1305
+ notificationsById[inboxNotification.id] = {
1221
1306
  ...inboxNotification,
1222
1307
  notifiedAt: optimisticUpdate.comment.createdAt,
1223
1308
  readAt: optimisticUpdate.comment.createdAt
@@ -1280,23 +1365,23 @@ function internalToExternalState(state, rawThreadsDB) {
1280
1365
  break;
1281
1366
  }
1282
1367
  case "mark-inbox-notification-as-read": {
1283
- const ibn = computed.notificationsById[optimisticUpdate.inboxNotificationId];
1368
+ const ibn = notificationsById[optimisticUpdate.inboxNotificationId];
1284
1369
  if (ibn === void 0) {
1285
1370
  break;
1286
1371
  }
1287
- computed.notificationsById[optimisticUpdate.inboxNotificationId] = {
1372
+ notificationsById[optimisticUpdate.inboxNotificationId] = {
1288
1373
  ...ibn,
1289
1374
  readAt: optimisticUpdate.readAt
1290
1375
  };
1291
1376
  break;
1292
1377
  }
1293
1378
  case "mark-all-inbox-notifications-as-read": {
1294
- for (const id in computed.notificationsById) {
1295
- const ibn = computed.notificationsById[id];
1379
+ for (const id in notificationsById) {
1380
+ const ibn = notificationsById[id];
1296
1381
  if (ibn === void 0) {
1297
1382
  break;
1298
1383
  }
1299
- computed.notificationsById[id] = {
1384
+ notificationsById[id] = {
1300
1385
  ...ibn,
1301
1386
  readAt: optimisticUpdate.readAt
1302
1387
  };
@@ -1304,38 +1389,44 @@ function internalToExternalState(state, rawThreadsDB) {
1304
1389
  break;
1305
1390
  }
1306
1391
  case "delete-inbox-notification": {
1307
- delete computed.notificationsById[optimisticUpdate.inboxNotificationId];
1392
+ delete notificationsById[optimisticUpdate.inboxNotificationId];
1308
1393
  break;
1309
1394
  }
1310
1395
  case "delete-all-inbox-notifications": {
1311
- computed.notificationsById = {};
1396
+ notificationsById = {};
1312
1397
  break;
1313
1398
  }
1399
+ }
1400
+ }
1401
+ const sortedNotifications = (
1402
+ // Sort so that the most recent notifications are first
1403
+ Object.values(notificationsById).filter(
1404
+ (ibn) => ibn.kind === "thread" ? threadsDB.get(ibn.threadId) !== void 0 : true
1405
+ ).sort((a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime())
1406
+ );
1407
+ return {
1408
+ sortedNotifications,
1409
+ notificationsById,
1410
+ threadsDB
1411
+ };
1412
+ }
1413
+ function applyOptimisticUpdates_forSettings(baseSettingsByRoomId, optimisticUpdates) {
1414
+ const settingsByRoomId = { ...baseSettingsByRoomId };
1415
+ for (const optimisticUpdate of optimisticUpdates) {
1416
+ switch (optimisticUpdate.type) {
1314
1417
  case "update-notification-settings": {
1315
- const settings = computed.settingsByRoomId[optimisticUpdate.roomId];
1418
+ const settings = settingsByRoomId[optimisticUpdate.roomId];
1316
1419
  if (settings === void 0) {
1317
1420
  break;
1318
1421
  }
1319
- computed.settingsByRoomId[optimisticUpdate.roomId] = {
1422
+ settingsByRoomId[optimisticUpdate.roomId] = {
1320
1423
  ...settings,
1321
1424
  ...optimisticUpdate.settings
1322
1425
  };
1323
1426
  }
1324
1427
  }
1325
1428
  }
1326
- const cleanedNotifications = (
1327
- // Sort so that the most recent notifications are first
1328
- Object.values(computed.notificationsById).filter(
1329
- (ibn) => ibn.kind === "thread" ? threadsDB.get(ibn.threadId) !== void 0 : true
1330
- ).sort((a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime())
1331
- );
1332
- return {
1333
- cleanedNotifications,
1334
- notificationsById: computed.notificationsById,
1335
- settingsByRoomId: computed.settingsByRoomId,
1336
- threadsDB,
1337
- versionsByRoomId: state.versionsByRoomId
1338
- };
1429
+ return settingsByRoomId;
1339
1430
  }
1340
1431
  function applyThreadDeltaUpdates(db, updates) {
1341
1432
  updates.newThreads.forEach((thread) => db.upsertIfNewer(thread));
@@ -1717,7 +1808,7 @@ function useInboxNotifications_withClient(client, selector, isEqual) {
1717
1808
  };
1718
1809
  }, [poller]);
1719
1810
  return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
1720
- store.subscribe,
1811
+ store.subscribe1_threads,
1721
1812
  store.getInboxNotificationsLoadingState,
1722
1813
  store.getInboxNotificationsLoadingState,
1723
1814
  selector,
@@ -1839,7 +1930,7 @@ function useDeleteAllInboxNotifications_withClient(client) {
1839
1930
  }
1840
1931
  function useInboxNotificationThread_withClient(client, inboxNotificationId) {
1841
1932
  const { store } = getLiveblocksExtrasForClient(client);
1842
- const getter = store.getFullState;
1933
+ const getter = store.get1_both;
1843
1934
  const selector = _react.useCallback.call(void 0,
1844
1935
  (state) => {
1845
1936
  const inboxNotification = _nullishCoalesce(state.notificationsById[inboxNotificationId], () => ( _core.raise.call(void 0, `Inbox notification with ID "${inboxNotificationId}" not found`)));
@@ -1856,7 +1947,7 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
1856
1947
  [inboxNotificationId]
1857
1948
  );
1858
1949
  return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
1859
- store.subscribe,
1950
+ store.subscribe1_both,
1860
1951
  // Re-evaluate if we need to update any time the notification changes over time
1861
1952
  getter,
1862
1953
  getter,
@@ -2072,7 +2163,7 @@ function useUserThreads_experimental(options = {
2072
2163
  [store, options.query]
2073
2164
  );
2074
2165
  return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
2075
- store.subscribe,
2166
+ store.subscribe1_threads,
2076
2167
  getter,
2077
2168
  getter,
2078
2169
  identity,
@@ -2281,8 +2372,21 @@ var UpdateNotificationSettingsError = class extends Error {
2281
2372
  }
2282
2373
  };
2283
2374
 
2375
+ // src/use-signal.ts
2376
+
2377
+ var identity2 = (value) => value;
2378
+ function useSignal(signal, selector, isEqual) {
2379
+ return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
2380
+ signal.subscribe,
2381
+ signal.get,
2382
+ signal.get,
2383
+ _nullishCoalesce(selector, () => ( identity2)),
2384
+ isEqual
2385
+ );
2386
+ }
2387
+
2284
2388
  // src/room.tsx
2285
- var _client2 = require('@liveblocks/client');
2389
+ var _client = require('@liveblocks/client');
2286
2390
 
2287
2391
 
2288
2392
 
@@ -2331,7 +2435,7 @@ function useScrollToCommentOnLoadEffect(shouldScrollOnLoad, state) {
2331
2435
  // src/room.tsx
2332
2436
  var noop3 = () => {
2333
2437
  };
2334
- var identity2 = (x) => x;
2438
+ var identity3 = (x) => x;
2335
2439
  var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\u2019re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you\u2019re ready to upgrade to React 18:
2336
2440
 
2337
2441
  import { unstable_batchedUpdates } from "react-dom"; // or "react-native"
@@ -2345,7 +2449,7 @@ var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\
2345
2449
  Why? Please see https://liveblocks.io/docs/platform/troubleshooting#stale-props-zombie-child for more information`;
2346
2450
  var superfluous_unstable_batchedUpdates = "You don\u2019t need to pass unstable_batchedUpdates to RoomProvider anymore, since you\u2019re on React 18+ already.";
2347
2451
  function useSyncExternalStore2(s, gs, gss) {
2348
- return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0, s, gs, gss, identity2);
2452
+ return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0, s, gs, gss, identity3);
2349
2453
  }
2350
2454
  var STABLE_EMPTY_LIST = Object.freeze([]);
2351
2455
  function alwaysEmptyList() {
@@ -2387,7 +2491,7 @@ function makeMutationContext(room) {
2387
2491
  };
2388
2492
  }
2389
2493
  function getCurrentUserId(client) {
2390
- const userId = client[_core.kInternal].currentUserIdStore.get();
2494
+ const userId = client[_core.kInternal].currentUserId.get();
2391
2495
  if (userId === void 0) {
2392
2496
  return "anonymous";
2393
2497
  }
@@ -2685,7 +2789,7 @@ function RoomProviderInner(props) {
2685
2789
  return;
2686
2790
  }
2687
2791
  const { thread, inboxNotification } = info;
2688
- const existingThread = store.getFullState().threadsDB.getEvenIfDeleted(message.threadId);
2792
+ const existingThread = store.get1_threads().threadsDB.getEvenIfDeleted(message.threadId);
2689
2793
  switch (message.type) {
2690
2794
  case _core.ServerMsgCode.COMMENT_EDITED:
2691
2795
  case _core.ServerMsgCode.THREAD_METADATA_UPDATED:
@@ -2750,6 +2854,52 @@ function useReportTextEditor(editor, rootKey) {
2750
2854
  return unsubscribe;
2751
2855
  }, [room, editor, rootKey]);
2752
2856
  }
2857
+ function useYjsProvider() {
2858
+ const room = useRoom();
2859
+ const subscribe = React4.useCallback(
2860
+ (onStoreChange) => {
2861
+ return room[_core.kInternal].yjsProviderDidChange.subscribe(onStoreChange);
2862
+ },
2863
+ [room]
2864
+ );
2865
+ const getSnapshot = React4.useCallback(() => {
2866
+ return room[_core.kInternal].getYjsProvider();
2867
+ }, [room]);
2868
+ return useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
2869
+ }
2870
+ function useCreateTextMention() {
2871
+ const room = useRoom();
2872
+ return React4.useCallback(
2873
+ (userId, mentionId) => {
2874
+ room[_core.kInternal].createTextMention(userId, mentionId).catch((err) => {
2875
+ _core.console.error(
2876
+ `Cannot create text mention for user '${userId}' and mention '${mentionId}'`,
2877
+ err
2878
+ );
2879
+ });
2880
+ },
2881
+ [room]
2882
+ );
2883
+ }
2884
+ function useDeleteTextMention() {
2885
+ const room = useRoom();
2886
+ return React4.useCallback(
2887
+ (mentionId) => {
2888
+ room[_core.kInternal].deleteTextMention(mentionId).catch((err) => {
2889
+ _core.console.error(`Cannot delete text mention '${mentionId}'`, err);
2890
+ });
2891
+ },
2892
+ [room]
2893
+ );
2894
+ }
2895
+ function useResolveMentionSuggestions() {
2896
+ const client = useClient();
2897
+ return client[_core.kInternal].resolveMentionSuggestions;
2898
+ }
2899
+ function useMentionSuggestionsCache() {
2900
+ const client = useClient();
2901
+ return client[_core.kInternal].mentionSuggestionsCache;
2902
+ }
2753
2903
  function useStorageStatus(options) {
2754
2904
  const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _14 => _14.smooth]), () => ( false)));
2755
2905
  if (smooth) {
@@ -2859,7 +3009,7 @@ function useSelf(maybeSelector, isEqual) {
2859
3009
  const room = useRoom();
2860
3010
  const subscribe = room.events.self.subscribe;
2861
3011
  const getSnapshot = room.getSelf;
2862
- const selector = _nullishCoalesce(maybeSelector, () => ( identity2));
3012
+ const selector = _nullishCoalesce(maybeSelector, () => ( identity3));
2863
3013
  const wrappedSelector = React4.useCallback(
2864
3014
  (me) => me !== null ? selector(me) : null,
2865
3015
  [selector]
@@ -2893,7 +3043,7 @@ function useOthers(selector, isEqual) {
2893
3043
  subscribe,
2894
3044
  getSnapshot,
2895
3045
  getServerSnapshot,
2896
- _nullishCoalesce(selector, () => ( identity2)),
3046
+ _nullishCoalesce(selector, () => ( identity3)),
2897
3047
  isEqual
2898
3048
  );
2899
3049
  }
@@ -2915,7 +3065,7 @@ function useOthersMapped(itemSelector, itemIsEqual) {
2915
3065
  return useOthers(wrappedSelector, wrappedIsEqual);
2916
3066
  }
2917
3067
  function useOthersConnectionIds() {
2918
- return useOthers(selectorFor_useOthersConnectionIds, _client2.shallow);
3068
+ return useOthers(selectorFor_useOthersConnectionIds, _client.shallow);
2919
3069
  }
2920
3070
  var NOT_FOUND = Symbol();
2921
3071
  function useOther(connectionId, selector, isEqual) {
@@ -3035,10 +3185,10 @@ function useThreads(options = {
3035
3185
  [store, room.id, options.query]
3036
3186
  );
3037
3187
  const state = _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
3038
- store.subscribe,
3188
+ store.subscribe1_threads,
3039
3189
  getter,
3040
3190
  getter,
3041
- identity2,
3191
+ identity3,
3042
3192
  shallow2
3043
3193
  // NOTE: Using 2-level-deep shallow check here, because the result of selectThreads() is not stable!
3044
3194
  );
@@ -3131,7 +3281,7 @@ function useDeleteRoomThread(roomId) {
3131
3281
  (threadId) => {
3132
3282
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3133
3283
  const userId = getCurrentUserId(client);
3134
- const existing = store.getFullState().threadsDB.get(threadId);
3284
+ const existing = store.get1_threads().threadsDB.get(threadId);
3135
3285
  if (_optionalChain([existing, 'optionalAccess', _17 => _17.comments, 'optionalAccess', _18 => _18[0], 'optionalAccess', _19 => _19.userId]) !== userId) {
3136
3286
  throw new Error("Only the thread creator can delete the thread");
3137
3287
  }
@@ -3254,7 +3404,7 @@ function useEditRoomComment(roomId) {
3254
3404
  ({ threadId, commentId, body, attachments }) => {
3255
3405
  const editedAt = /* @__PURE__ */ new Date();
3256
3406
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3257
- const existing = store.getFullState().threadsDB.getEvenIfDeleted(threadId);
3407
+ const existing = store.get1_threads().threadsDB.getEvenIfDeleted(threadId);
3258
3408
  if (existing === void 0) {
3259
3409
  _core.console.warn(
3260
3410
  `Internal unexpected behavior. Cannot edit comment in thread "${threadId}" because the thread does not exist in the cache.`
@@ -3436,7 +3586,7 @@ function useMarkRoomThreadAsRead(roomId) {
3436
3586
  (threadId) => {
3437
3587
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3438
3588
  const inboxNotification = Object.values(
3439
- store.getFullState().notificationsById
3589
+ store.get1_notifications().notificationsById
3440
3590
  ).find(
3441
3591
  (inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
3442
3592
  );
@@ -3548,9 +3698,10 @@ function useMarkRoomThreadAsUnresolved(roomId) {
3548
3698
  function useThreadSubscription(threadId) {
3549
3699
  const client = useClient();
3550
3700
  const { store } = getRoomExtrasForClient(client);
3701
+ const signal = store.outputs.threadifications;
3551
3702
  const selector = React4.useCallback(
3552
3703
  (state) => {
3553
- const notification = state.cleanedNotifications.find(
3704
+ const notification = state.sortedNotifications.find(
3554
3705
  (inboxNotification) => inboxNotification.kind === "thread" && inboxNotification.threadId === threadId
3555
3706
  );
3556
3707
  const thread = state.threadsDB.get(threadId);
@@ -3564,12 +3715,7 @@ function useThreadSubscription(threadId) {
3564
3715
  },
3565
3716
  [threadId]
3566
3717
  );
3567
- return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
3568
- store.subscribe,
3569
- store.getFullState,
3570
- store.getFullState,
3571
- selector
3572
- );
3718
+ return useSignal(signal, selector, _client.shallow);
3573
3719
  }
3574
3720
  function useRoomNotificationSettings() {
3575
3721
  const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
@@ -3602,10 +3748,10 @@ function useRoomNotificationSettings() {
3602
3748
  [store, room.id]
3603
3749
  );
3604
3750
  const settings = _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
3605
- store.subscribe,
3751
+ store.subscribe2,
3606
3752
  getter,
3607
3753
  getter,
3608
- identity2,
3754
+ identity3,
3609
3755
  shallow2
3610
3756
  );
3611
3757
  return React4.useMemo(() => {
@@ -3681,10 +3827,10 @@ function useHistoryVersions() {
3681
3827
  // *next* render after that, a *new* fetch/promise will get created.
3682
3828
  );
3683
3829
  const state = _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
3684
- store.subscribe,
3830
+ store.subscribe3,
3685
3831
  getter,
3686
3832
  getter,
3687
- identity2,
3833
+ identity3,
3688
3834
  shallow2
3689
3835
  );
3690
3836
  return state;
@@ -3828,7 +3974,7 @@ function useRoomAttachmentUrl(attachmentId, roomId) {
3828
3974
  getAttachmentUrlState,
3829
3975
  getAttachmentUrlState,
3830
3976
  selectorFor_useAttachmentUrl,
3831
- _client2.shallow
3977
+ _client.shallow
3832
3978
  );
3833
3979
  }
3834
3980
  function useAttachmentUrlSuspense(attachmentId) {
@@ -3862,11 +4008,10 @@ function useAttachmentUrlSuspense(attachmentId) {
3862
4008
  function useRoomPermissions(roomId) {
3863
4009
  const client = useClient();
3864
4010
  const store = getRoomExtrasForClient(client).store;
3865
- return _nullishCoalesce(useSyncExternalStore2(
3866
- store.subscribe,
3867
- React4.useCallback(() => store._getPermissions(roomId), [store, roomId]),
3868
- React4.useCallback(() => store._getPermissions(roomId), [store, roomId])
3869
- ), () => ( /* @__PURE__ */ new Set()));
4011
+ return useSignal(
4012
+ store.permissionHintsByRoomId,
4013
+ (hints) => _nullishCoalesce(hints[roomId], () => ( /* @__PURE__ */ new Set()))
4014
+ );
3870
4015
  }
3871
4016
  function createRoomContext(client) {
3872
4017
  return getOrCreateRoomContextBundle(client);
@@ -4007,5 +4152,11 @@ var _useUpdateMyPresence = useUpdateMyPresence;
4007
4152
 
4008
4153
 
4009
4154
 
4010
- exports.RoomContext = RoomContext; exports.useRoomOrNull = useRoomOrNull; exports.ClientContext = ClientContext; exports.getUmbrellaStoreForClient = getUmbrellaStoreForClient; exports.useClientOrNull = useClientOrNull; 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; exports.useSyncStatus = useSyncStatus; exports.CreateThreadError = CreateThreadError; exports.useStatus = useStatus; exports.useReportTextEditor = useReportTextEditor; 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.useCreateRoomThread = useCreateRoomThread; exports.useDeleteRoomThread = useDeleteRoomThread; exports.useEditRoomThreadMetadata = useEditRoomThreadMetadata; exports.useCreateComment = useCreateComment; exports.useCreateRoomComment = useCreateRoomComment; exports.useEditComment = useEditComment; exports.useEditRoomComment = useEditRoomComment; exports.useDeleteComment = useDeleteComment; exports.useDeleteRoomComment = useDeleteRoomComment; exports.useAddRoomCommentReaction = useAddRoomCommentReaction; exports.useRemoveReaction = useRemoveReaction; exports.useRemoveRoomCommentReaction = useRemoveRoomCommentReaction; exports.useMarkThreadAsRead = useMarkThreadAsRead; exports.useMarkRoomThreadAsRead = useMarkRoomThreadAsRead; exports.useMarkThreadAsResolved = useMarkThreadAsResolved; exports.useMarkRoomThreadAsResolved = useMarkRoomThreadAsResolved; exports.useMarkThreadAsUnresolved = useMarkThreadAsUnresolved; exports.useMarkRoomThreadAsUnresolved = useMarkRoomThreadAsUnresolved; exports.useThreadSubscription = useThreadSubscription; exports.useHistoryVersionData = useHistoryVersionData; exports.useUpdateRoomNotificationSettings = useUpdateRoomNotificationSettings; exports.useOthersConnectionIdsSuspense = useOthersConnectionIdsSuspense; exports.useStorageStatusSuspense = useStorageStatusSuspense; exports.useAttachmentUrl = useAttachmentUrl; exports.useRoomAttachmentUrl = useRoomAttachmentUrl; exports.useAttachmentUrlSuspense = useAttachmentUrlSuspense; exports.useRoomPermissions = useRoomPermissions; 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._useRoomNotificationSettings = _useRoomNotificationSettings; exports._useRoomNotificationSettingsSuspense = _useRoomNotificationSettingsSuspense; 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;
4011
- //# sourceMappingURL=chunk-X4DDEZYL.js.map
4155
+
4156
+
4157
+
4158
+
4159
+
4160
+
4161
+ exports.RoomContext = RoomContext; exports.useRoomOrNull = useRoomOrNull; exports.ClientContext = ClientContext; exports.getUmbrellaStoreForClient = getUmbrellaStoreForClient; exports.useClientOrNull = useClientOrNull; 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; exports.useSyncStatus = useSyncStatus; exports.CreateThreadError = CreateThreadError; exports.useSignal = useSignal; exports.useStatus = useStatus; exports.useReportTextEditor = useReportTextEditor; exports.useYjsProvider = useYjsProvider; exports.useCreateTextMention = useCreateTextMention; exports.useDeleteTextMention = useDeleteTextMention; exports.useResolveMentionSuggestions = useResolveMentionSuggestions; exports.useMentionSuggestionsCache = useMentionSuggestionsCache; 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.useCreateRoomThread = useCreateRoomThread; exports.useDeleteRoomThread = useDeleteRoomThread; exports.useEditRoomThreadMetadata = useEditRoomThreadMetadata; exports.useCreateComment = useCreateComment; exports.useCreateRoomComment = useCreateRoomComment; exports.useEditComment = useEditComment; exports.useEditRoomComment = useEditRoomComment; exports.useDeleteComment = useDeleteComment; exports.useDeleteRoomComment = useDeleteRoomComment; exports.useAddRoomCommentReaction = useAddRoomCommentReaction; exports.useRemoveReaction = useRemoveReaction; exports.useRemoveRoomCommentReaction = useRemoveRoomCommentReaction; exports.useMarkThreadAsRead = useMarkThreadAsRead; exports.useMarkRoomThreadAsRead = useMarkRoomThreadAsRead; exports.useMarkThreadAsResolved = useMarkThreadAsResolved; exports.useMarkRoomThreadAsResolved = useMarkRoomThreadAsResolved; exports.useMarkThreadAsUnresolved = useMarkThreadAsUnresolved; exports.useMarkRoomThreadAsUnresolved = useMarkRoomThreadAsUnresolved; exports.useThreadSubscription = useThreadSubscription; exports.useHistoryVersionData = useHistoryVersionData; exports.useUpdateRoomNotificationSettings = useUpdateRoomNotificationSettings; exports.useOthersConnectionIdsSuspense = useOthersConnectionIdsSuspense; exports.useStorageStatusSuspense = useStorageStatusSuspense; exports.useAttachmentUrl = useAttachmentUrl; exports.useRoomAttachmentUrl = useRoomAttachmentUrl; exports.useAttachmentUrlSuspense = useAttachmentUrlSuspense; exports.useRoomPermissions = useRoomPermissions; 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._useRoomNotificationSettings = _useRoomNotificationSettings; exports._useRoomNotificationSettingsSuspense = _useRoomNotificationSettingsSuspense; 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;
4162
+ //# sourceMappingURL=chunk-N33NEN5R.js.map