@liveblocks/react 1.3.4 → 1.3.6

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.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ var _core = require('@liveblocks/core');
5
5
 
6
6
  // src/version.ts
7
7
  var PKG_NAME = "@liveblocks/react";
8
- var PKG_VERSION = "1.3.4";
8
+ var PKG_VERSION = "1.3.6";
9
9
  var PKG_FORMAT = "cjs";
10
10
 
11
11
  // src/ClientSideSuspense.tsx
@@ -32,6 +32,8 @@ var _withselectorjs = require('use-sync-external-store/shim/with-selector.js');
32
32
 
33
33
  // src/comments/CommentsRoom.ts
34
34
 
35
+
36
+
35
37
  var _nanoid = require('nanoid');
36
38
 
37
39
  var _indexjs = require('use-sync-external-store/shim/index.js');
@@ -78,158 +80,166 @@ var DeleteCommentError = class extends Error {
78
80
  }
79
81
  };
80
82
 
81
- // src/comments/lib/store.ts
82
-
83
- function createStore(initialState) {
84
- let state = initialState;
83
+ // src/comments/CommentsRoom.ts
84
+ var POLLING_INTERVAL_REALTIME = 3e4;
85
+ var POLLING_INTERVAL = 5e3;
86
+ var MAX_ERROR_RETRY_COUNT = 5;
87
+ var ERROR_RETRY_INTERVAL = 5e3;
88
+ var THREAD_ID_PREFIX = "th";
89
+ var COMMENT_ID_PREFIX = "cm";
90
+ var DEDUPING_INTERVAL = 1e3;
91
+ function createOptimisticId(prefix) {
92
+ return `${prefix}_${_nanoid.nanoid.call(void 0, )}`;
93
+ }
94
+ function createThreadsManager() {
95
+ let cache;
96
+ let request;
97
+ let mutation;
85
98
  const eventSource = _core.makeEventSource.call(void 0, );
86
99
  return {
87
- get() {
88
- return state;
100
+ get cache() {
101
+ return cache;
89
102
  },
90
- set(newState) {
91
- state = newState;
92
- eventSource.notify(state);
103
+ set cache(value) {
104
+ cache = value;
105
+ eventSource.notify(cache);
93
106
  },
94
- subscribe(callback) {
95
- return eventSource.subscribe(callback);
107
+ get request() {
108
+ return request;
96
109
  },
97
- subscribeOnce(callback) {
98
- return eventSource.subscribeOnce(callback);
110
+ set request(value) {
111
+ request = value;
99
112
  },
100
- subscribersCount() {
101
- return eventSource.count();
113
+ get mutation() {
114
+ return mutation;
102
115
  },
103
- destroy() {
104
- return eventSource.clear();
116
+ set mutation(value) {
117
+ mutation = value;
118
+ },
119
+ subscribe(callback) {
120
+ return eventSource.subscribe(callback);
105
121
  }
106
122
  };
107
123
  }
108
-
109
- // src/comments/CommentsRoom.ts
110
- var POLLING_INTERVAL_REALTIME = 3e4;
111
- var POLLING_INTERVAL = 5e3;
112
- var THREAD_ID_PREFIX = "th";
113
- var COMMENT_ID_PREFIX = "cm";
114
- function createOptimisticId(prefix) {
115
- return `${prefix}_${_nanoid.nanoid.call(void 0, )}`;
116
- }
117
124
  function createCommentsRoom(room, errorEventSource) {
118
- const store = createStore({
119
- isLoading: true
120
- });
121
- let fetchThreadsPromise = null;
122
- let numberOfMutations = 0;
123
- function endMutation() {
124
- numberOfMutations--;
125
- if (numberOfMutations === 0) {
126
- void revalidateThreads();
127
- }
128
- }
129
- function startMutation() {
130
- pollingHub.threads.stop();
131
- numberOfMutations++;
132
- }
133
- const pollingHub = {
134
- // TODO: If there's an error, it will currently infinitely retry at the current polling rate → add retry logic
135
- threads: _core.makePoller.call(void 0, revalidateThreads)
136
- };
137
- let unsubscribeRealtimeEvents;
138
- let unsubscribeRealtimeConnection;
139
- let realtimeClientConnected = false;
140
- function getPollingInterval() {
141
- return realtimeClientConnected ? POLLING_INTERVAL_REALTIME : POLLING_INTERVAL;
142
- }
143
- function ensureThreadsAreLoadedForMutations() {
144
- const state = store.get();
145
- if (state.isLoading || state.error) {
146
- throw new Error(
147
- "Cannot update threads or comments before they are loaded"
148
- );
149
- }
150
- return state.threads;
151
- }
152
- async function revalidateThreads() {
153
- pollingHub.threads.pause();
154
- if (numberOfMutations === 0) {
155
- if (fetchThreadsPromise === null) {
156
- fetchThreadsPromise = room.getThreads();
125
+ const manager = createThreadsManager();
126
+ let timestamp = 0;
127
+ let commentsEventRefCount = 0;
128
+ let commentsEventDisposer;
129
+ async function mutate(data, options) {
130
+ const beforeMutationTimestamp = ++timestamp;
131
+ manager.mutation = {
132
+ startTime: beforeMutationTimestamp,
133
+ endTime: 0
134
+ };
135
+ const currentCache = manager.cache;
136
+ manager.cache = {
137
+ isLoading: false,
138
+ threads: options.optimisticData
139
+ };
140
+ try {
141
+ await data;
142
+ const activeMutation = manager.mutation;
143
+ if (activeMutation && beforeMutationTimestamp !== activeMutation.startTime) {
144
+ return;
157
145
  }
158
- setThreads(await fetchThreadsPromise);
159
- fetchThreadsPromise = null;
146
+ } catch (err) {
147
+ manager.cache = currentCache;
148
+ throw err;
160
149
  }
161
- pollingHub.threads.resume();
162
- }
163
- function subscribe() {
164
- if (!unsubscribeRealtimeEvents) {
165
- unsubscribeRealtimeEvents = room.events.comments.subscribe(() => {
166
- pollingHub.threads.restart(getPollingInterval());
167
- void revalidateThreads();
168
- });
150
+ manager.mutation = {
151
+ startTime: beforeMutationTimestamp,
152
+ endTime: ++timestamp
153
+ };
154
+ manager.request = void 0;
155
+ void revalidateCache(false);
156
+ }
157
+ async function revalidateCache(shouldDedupe, retryCount = 0) {
158
+ let startAt;
159
+ const shouldStartRequest = !manager.request || !shouldDedupe;
160
+ function deleteActiveRequest() {
161
+ const activeRequest = manager.request;
162
+ if (!activeRequest)
163
+ return;
164
+ if (activeRequest.timestamp !== startAt)
165
+ return;
166
+ manager.request = void 0;
169
167
  }
170
- if (!unsubscribeRealtimeConnection) {
171
- unsubscribeRealtimeConnection = room.events.status.subscribe((status) => {
172
- const nextRealtimeClientConnected = status === "connected";
173
- if (nextRealtimeClientConnected !== realtimeClientConnected) {
174
- realtimeClientConnected = nextRealtimeClientConnected;
175
- pollingHub.threads.restart(getPollingInterval());
176
- }
177
- });
168
+ function handleError() {
169
+ const timeout = ~~((Math.random() + 0.5) * (1 << (retryCount < 8 ? retryCount : 8))) * ERROR_RETRY_INTERVAL;
170
+ if (retryCount > MAX_ERROR_RETRY_COUNT)
171
+ return;
172
+ setTimeout(() => {
173
+ void revalidateCache(true, retryCount + 1);
174
+ }, timeout);
178
175
  }
179
- pollingHub.threads.start(getPollingInterval());
180
- return () => {
181
- if (store.subscribersCount() > 1) {
176
+ try {
177
+ if (shouldStartRequest) {
178
+ const currentCache = manager.cache;
179
+ if (!currentCache)
180
+ manager.cache = { isLoading: true };
181
+ manager.request = {
182
+ fetcher: room.getThreads(),
183
+ timestamp: ++timestamp
184
+ };
185
+ }
186
+ const activeRequest = manager.request;
187
+ if (!activeRequest)
182
188
  return;
189
+ const newData = await activeRequest.fetcher;
190
+ startAt = activeRequest.timestamp;
191
+ if (shouldStartRequest) {
192
+ setTimeout(deleteActiveRequest, DEDUPING_INTERVAL);
183
193
  }
184
- pollingHub.threads.stop();
185
- _optionalChain([unsubscribeRealtimeEvents, 'optionalCall', _ => _()]);
186
- unsubscribeRealtimeEvents = void 0;
187
- _optionalChain([unsubscribeRealtimeConnection, 'optionalCall', _2 => _2()]);
188
- unsubscribeRealtimeConnection = void 0;
189
- };
190
- }
191
- function setThreads(newThreads) {
192
- store.set({
193
- threads: newThreads,
194
- isLoading: false
195
- });
196
- }
197
- function useThreadsInternal() {
198
- _react.useEffect.call(void 0, subscribe, []);
199
- return _indexjs.useSyncExternalStore.call(void 0,
200
- store.subscribe,
201
- store.get,
202
- store.get
203
- );
204
- }
205
- function useThreads() {
206
- _react.useEffect.call(void 0, () => {
207
- void revalidateThreads();
208
- }, []);
209
- return useThreadsInternal();
210
- }
211
- function useThreadsSuspense() {
212
- const result = useThreadsInternal();
213
- if (result.isLoading) {
214
- throw revalidateThreads();
215
- }
216
- if (result.error) {
217
- throw result.error;
194
+ if (!manager.request || manager.request.timestamp !== startAt)
195
+ return;
196
+ const activeMutation = manager.mutation;
197
+ if (activeMutation && (activeMutation.startTime > startAt || activeMutation.endTime > startAt || activeMutation.endTime === 0)) {
198
+ return;
199
+ }
200
+ manager.cache = {
201
+ isLoading: false,
202
+ threads: newData
203
+ };
204
+ } catch (err) {
205
+ if (shouldStartRequest)
206
+ handleError();
207
+ deleteActiveRequest();
208
+ manager.cache = {
209
+ isLoading: false,
210
+ error: err
211
+ };
218
212
  }
219
- return result.threads;
220
213
  }
221
- function getCurrentUserId() {
222
- const self = room.getSelf();
223
- if (self === null || self.id === void 0) {
224
- return "anonymous";
225
- } else {
226
- return self.id;
227
- }
214
+ function editThreadMetadata(options) {
215
+ const threadId = options.threadId;
216
+ const metadata = "metadata" in options ? options.metadata : {};
217
+ const threads = getThreads();
218
+ const optimisticData = threads.map(
219
+ (thread) => thread.id === threadId ? {
220
+ ...thread,
221
+ metadata: {
222
+ ...thread.metadata,
223
+ ...metadata
224
+ }
225
+ } : thread
226
+ );
227
+ mutate(room.editThreadMetadata({ metadata, threadId }), {
228
+ optimisticData
229
+ }).catch((err) => {
230
+ errorEventSource.notify(
231
+ new EditThreadMetadataError(err, {
232
+ roomId: room.id,
233
+ threadId,
234
+ metadata
235
+ })
236
+ );
237
+ });
228
238
  }
229
239
  function createThread(options) {
230
240
  const body = options.body;
231
241
  const metadata = "metadata" in options ? options.metadata : {};
232
- const threads = ensureThreadsAreLoadedForMutations();
242
+ const threads = getThreads();
233
243
  const threadId = createOptimisticId(THREAD_ID_PREFIX);
234
244
  const commentId = createOptimisticId(COMMENT_ID_PREFIX);
235
245
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -249,9 +259,9 @@ function createCommentsRoom(room, errorEventSource) {
249
259
  }
250
260
  ]
251
261
  };
252
- setThreads([...threads, newThread]);
253
- startMutation();
254
- room.createThread({ threadId, commentId, body, metadata }).catch(
262
+ mutate(room.createThread({ threadId, commentId, body, metadata }), {
263
+ optimisticData: [...threads, newThread]
264
+ }).catch(
255
265
  (er) => errorEventSource.notify(
256
266
  new CreateThreadError(er, {
257
267
  roomId: room.id,
@@ -261,40 +271,14 @@ function createCommentsRoom(room, errorEventSource) {
261
271
  metadata
262
272
  })
263
273
  )
264
- ).finally(endMutation);
265
- return newThread;
266
- }
267
- function editThreadMetadata(options) {
268
- const threadId = options.threadId;
269
- const metadata = "metadata" in options ? options.metadata : {};
270
- const threads = ensureThreadsAreLoadedForMutations();
271
- setThreads(
272
- threads.map(
273
- (thread) => thread.id === threadId ? {
274
- ...thread,
275
- metadata: {
276
- ...thread.metadata,
277
- ...metadata
278
- }
279
- } : thread
280
- )
281
274
  );
282
- startMutation();
283
- room.editThreadMetadata({ metadata, threadId }).catch(
284
- (er) => errorEventSource.notify(
285
- new EditThreadMetadataError(er, {
286
- roomId: room.id,
287
- threadId,
288
- metadata
289
- })
290
- )
291
- ).finally(endMutation);
275
+ return newThread;
292
276
  }
293
277
  function createComment({
294
278
  threadId,
295
279
  body
296
280
  }) {
297
- const threads = ensureThreadsAreLoadedForMutations();
281
+ const threads = getThreads();
298
282
  const commentId = createOptimisticId(COMMENT_ID_PREFIX);
299
283
  const now = (/* @__PURE__ */ new Date()).toISOString();
300
284
  const comment = {
@@ -306,16 +290,15 @@ function createCommentsRoom(room, errorEventSource) {
306
290
  userId: getCurrentUserId(),
307
291
  body
308
292
  };
309
- setThreads(
310
- threads.map(
311
- (thread) => thread.id === threadId ? {
312
- ...thread,
313
- comments: [...thread.comments, comment]
314
- } : thread
315
- )
293
+ const optimisticData = threads.map(
294
+ (thread) => thread.id === threadId ? {
295
+ ...thread,
296
+ comments: [...thread.comments, comment]
297
+ } : thread
316
298
  );
317
- startMutation();
318
- room.createComment({ threadId, commentId, body }).catch(
299
+ mutate(room.createComment({ threadId, commentId, body }), {
300
+ optimisticData
301
+ }).catch(
319
302
  (er) => errorEventSource.notify(
320
303
  new CreateCommentError(er, {
321
304
  roomId: room.id,
@@ -324,28 +307,27 @@ function createCommentsRoom(room, errorEventSource) {
324
307
  body
325
308
  })
326
309
  )
327
- ).finally(endMutation);
310
+ );
328
311
  return comment;
329
312
  }
330
313
  function editComment({ threadId, commentId, body }) {
331
- const threads = ensureThreadsAreLoadedForMutations();
314
+ const threads = getThreads();
332
315
  const now = (/* @__PURE__ */ new Date()).toISOString();
333
- setThreads(
334
- threads.map(
335
- (thread) => thread.id === threadId ? {
336
- ...thread,
337
- comments: thread.comments.map(
338
- (comment) => comment.id === commentId ? {
339
- ...comment,
340
- editedAt: now,
341
- body
342
- } : comment
343
- )
344
- } : thread
345
- )
316
+ const optimisticData = threads.map(
317
+ (thread) => thread.id === threadId ? {
318
+ ...thread,
319
+ comments: thread.comments.map(
320
+ (comment) => comment.id === commentId ? {
321
+ ...comment,
322
+ editedAt: now,
323
+ body
324
+ } : comment
325
+ )
326
+ } : thread
346
327
  );
347
- startMutation();
348
- room.editComment({ threadId, commentId, body }).catch(
328
+ mutate(room.editComment({ threadId, commentId, body }), {
329
+ optimisticData
330
+ }).catch(
349
331
  (er) => errorEventSource.notify(
350
332
  new EditCommentError(er, {
351
333
  roomId: room.id,
@@ -354,10 +336,10 @@ function createCommentsRoom(room, errorEventSource) {
354
336
  body
355
337
  })
356
338
  )
357
- ).finally(endMutation);
339
+ );
358
340
  }
359
341
  function deleteComment({ threadId, commentId }) {
360
- const threads = ensureThreadsAreLoadedForMutations();
342
+ const threads = getThreads();
361
343
  const now = (/* @__PURE__ */ new Date()).toISOString();
362
344
  const newThreads = [];
363
345
  for (const thread of threads) {
@@ -379,9 +361,9 @@ function createCommentsRoom(room, errorEventSource) {
379
361
  newThreads.push(thread);
380
362
  }
381
363
  }
382
- setThreads(newThreads);
383
- startMutation();
384
- room.deleteComment({ threadId, commentId }).catch(
364
+ mutate(room.deleteComment({ threadId, commentId }), {
365
+ optimisticData: newThreads
366
+ }).catch(
385
367
  (er) => errorEventSource.notify(
386
368
  new DeleteCommentError(er, {
387
369
  roomId: room.id,
@@ -389,13 +371,103 @@ function createCommentsRoom(room, errorEventSource) {
389
371
  commentId
390
372
  })
391
373
  )
392
- ).finally(endMutation);
374
+ );
375
+ }
376
+ function getCurrentUserId() {
377
+ const self = room.getSelf();
378
+ if (self === null || self.id === void 0) {
379
+ return "anonymous";
380
+ } else {
381
+ return self.id;
382
+ }
383
+ }
384
+ function getThreads() {
385
+ const threads = manager.cache;
386
+ if (!threads || threads.isLoading || threads.error) {
387
+ throw new Error(
388
+ "Cannot update threads or comments before they are loaded."
389
+ );
390
+ }
391
+ return threads.threads;
392
+ }
393
+ function _subscribe() {
394
+ if (commentsEventRefCount === 0) {
395
+ commentsEventDisposer = room.events.comments.subscribe(() => {
396
+ void revalidateCache(true);
397
+ });
398
+ }
399
+ commentsEventRefCount = commentsEventRefCount + 1;
400
+ return () => {
401
+ commentsEventRefCount = commentsEventRefCount - 1;
402
+ if (commentsEventRefCount > 0)
403
+ return;
404
+ _optionalChain([commentsEventDisposer, 'optionalCall', _ => _()]);
405
+ commentsEventDisposer = void 0;
406
+ };
407
+ }
408
+ function usePolling() {
409
+ const status = _indexjs.useSyncExternalStore.call(void 0,
410
+ room.events.status.subscribe,
411
+ room.getStatus,
412
+ room.getStatus
413
+ );
414
+ _react.useEffect.call(void 0,
415
+ () => {
416
+ const interval = status === "connected" ? POLLING_INTERVAL_REALTIME : POLLING_INTERVAL;
417
+ let revalidationTimerId;
418
+ function scheduleRevalidation() {
419
+ revalidationTimerId = window.setTimeout(
420
+ executeRevalidation,
421
+ interval
422
+ );
423
+ }
424
+ function executeRevalidation() {
425
+ void revalidateCache(true).then(scheduleRevalidation);
426
+ }
427
+ scheduleRevalidation();
428
+ return () => {
429
+ window.clearTimeout(revalidationTimerId);
430
+ };
431
+ },
432
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- ESLint recommends against adding `revalidateCache` as a dependency, but not doing so causes the code inside `useEffect` to reference an outdated version of `revalidateCache`
433
+ [status, revalidateCache]
434
+ );
435
+ }
436
+ function useThreadsInternal() {
437
+ _react.useEffect.call(void 0, _subscribe, [_subscribe]);
438
+ usePolling();
439
+ const cache = _indexjs.useSyncExternalStore.call(void 0,
440
+ manager.subscribe,
441
+ () => manager.cache,
442
+ () => manager.cache
443
+ );
444
+ return _nullishCoalesce(cache, () => ( { isLoading: true }));
445
+ }
446
+ function useThreads() {
447
+ _react.useEffect.call(void 0,
448
+ () => {
449
+ void revalidateCache(true);
450
+ },
451
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- ESLint recommends against adding `revalidateCache` as a dependency, but not doing so causes the code inside `useEffect` to reference an outdated version of `revalidateCache`
452
+ [revalidateCache]
453
+ );
454
+ return useThreadsInternal();
455
+ }
456
+ function useThreadsSuspense() {
457
+ const cache = useThreadsInternal();
458
+ if (cache.isLoading) {
459
+ throw revalidateCache(true);
460
+ }
461
+ if (cache.error) {
462
+ throw cache.error;
463
+ }
464
+ return cache.threads;
393
465
  }
394
466
  return {
395
467
  useThreads,
396
468
  useThreadsSuspense,
397
- createThread,
398
469
  editThreadMetadata,
470
+ createThread,
399
471
  createComment,
400
472
  editComment,
401
473
  deleteComment
@@ -462,31 +534,31 @@ function useAsyncCache(cache, key, options) {
462
534
  if (key === null || !cache) {
463
535
  return null;
464
536
  }
465
- const cacheItem2 = cache.create(key, _optionalChain([frozenOptions, 'optionalAccess', _3 => _3.overrideFunction]));
537
+ const cacheItem2 = cache.create(key, _optionalChain([frozenOptions, 'optionalAccess', _2 => _2.overrideFunction]));
466
538
  void cacheItem2.get();
467
539
  return cacheItem2;
468
540
  }, [cache, frozenOptions, key]);
469
541
  const subscribe = _react.useCallback.call(void 0,
470
- (callback) => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess', _4 => _4.subscribe, 'call', _5 => _5(callback)]), () => ( noop)),
542
+ (callback) => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess', _3 => _3.subscribe, 'call', _4 => _4(callback)]), () => ( noop)),
471
543
  [cacheItem]
472
544
  );
473
545
  const getState = _react.useCallback.call(void 0,
474
- () => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess', _6 => _6.getState, 'call', _7 => _7()]), () => ( INITIAL_ASYNC_STATE)),
546
+ () => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess', _5 => _5.getState, 'call', _6 => _6()]), () => ( INITIAL_ASYNC_STATE)),
475
547
  [cacheItem]
476
548
  );
477
- const revalidate = _react.useCallback.call(void 0, () => _optionalChain([cacheItem, 'optionalAccess', _8 => _8.revalidate, 'call', _9 => _9()]), [cacheItem]);
549
+ const revalidate = _react.useCallback.call(void 0, () => _optionalChain([cacheItem, 'optionalAccess', _7 => _7.revalidate, 'call', _8 => _8()]), [cacheItem]);
478
550
  const state = _indexjs.useSyncExternalStore.call(void 0, subscribe, getState, getState);
479
551
  const previousData = _react.useRef.call(void 0, );
480
552
  let data = state.data;
481
553
  _react.useEffect.call(void 0, () => {
482
554
  previousData.current = { key, data: state.data };
483
555
  }, [key, state]);
484
- if (_optionalChain([frozenOptions, 'optionalAccess', _10 => _10.suspense]) && state.isLoading && cacheItem) {
556
+ if (_optionalChain([frozenOptions, 'optionalAccess', _9 => _9.suspense]) && state.isLoading && cacheItem) {
485
557
  throw new Promise((resolve) => {
486
558
  cacheItem.subscribeOnce(() => resolve());
487
559
  });
488
560
  }
489
- if (state.isLoading && _optionalChain([frozenOptions, 'optionalAccess', _11 => _11.keepPreviousDataWhileLoading]) && typeof state.data === "undefined" && _optionalChain([previousData, 'access', _12 => _12.current, 'optionalAccess', _13 => _13.key]) !== key && typeof _optionalChain([previousData, 'access', _14 => _14.current, 'optionalAccess', _15 => _15.data]) !== "undefined") {
561
+ if (state.isLoading && _optionalChain([frozenOptions, 'optionalAccess', _10 => _10.keepPreviousDataWhileLoading]) && typeof state.data === "undefined" && _optionalChain([previousData, 'access', _11 => _11.current, 'optionalAccess', _12 => _12.key]) !== key && typeof _optionalChain([previousData, 'access', _13 => _13.current, 'optionalAccess', _14 => _14.data]) !== "undefined") {
490
562
  data = previousData.current.data;
491
563
  }
492
564
  return {
@@ -642,9 +714,9 @@ function createRoomContext(client, options) {
642
714
  );
643
715
  setRoom(room2);
644
716
  return () => {
645
- const commentsRoom = commentsRooms.get(roomId);
717
+ const commentsRoom = commentsRooms.get(room2);
646
718
  if (commentsRoom) {
647
- commentsRooms.delete(roomId);
719
+ commentsRooms.delete(room2);
648
720
  }
649
721
  client.leave(roomId);
650
722
  };
@@ -863,7 +935,7 @@ function createRoomContext(client, options) {
863
935
  function onRootChange() {
864
936
  const newValue = root.get(key);
865
937
  if (newValue !== curr) {
866
- _optionalChain([unsubCurr, 'optionalCall', _16 => _16()]);
938
+ _optionalChain([unsubCurr, 'optionalCall', _15 => _15()]);
867
939
  curr = newValue;
868
940
  subscribeToCurr();
869
941
  rerender();
@@ -874,7 +946,7 @@ function createRoomContext(client, options) {
874
946
  const unsubscribeRoot = room.subscribe(root, onRootChange);
875
947
  return () => {
876
948
  unsubscribeRoot();
877
- _optionalChain([unsubCurr, 'optionalCall', _17 => _17()]);
949
+ _optionalChain([unsubCurr, 'optionalCall', _16 => _16()]);
878
950
  };
879
951
  }, [rootOrNull, room, key, rerender]);
880
952
  if (rootOrNull === null) {
@@ -1000,10 +1072,10 @@ function createRoomContext(client, options) {
1000
1072
  const commentsErrorEventSource = _core.makeEventSource.call(void 0, );
1001
1073
  const commentsRooms = /* @__PURE__ */ new Map();
1002
1074
  function getCommentsRoom(room) {
1003
- let commentsRoom = commentsRooms.get(room.id);
1075
+ let commentsRoom = commentsRooms.get(room);
1004
1076
  if (commentsRoom === void 0) {
1005
1077
  commentsRoom = createCommentsRoom(room, commentsErrorEventSource);
1006
- commentsRooms.set(room.id, commentsRoom);
1078
+ commentsRooms.set(room, commentsRoom);
1007
1079
  }
1008
1080
  return commentsRoom;
1009
1081
  }