@liveblocks/react 1.9.2 → 1.9.3
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.d.mts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +316 -419
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +335 -438
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { detectDupes } from "@liveblocks/core";
|
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
7
|
var PKG_NAME = "@liveblocks/react";
|
|
8
|
-
var PKG_VERSION = "1.9.
|
|
8
|
+
var PKG_VERSION = "1.9.3";
|
|
9
9
|
var PKG_FORMAT = "esm";
|
|
10
10
|
|
|
11
11
|
// src/ClientSideSuspense.tsx
|
|
@@ -29,20 +29,19 @@ import {
|
|
|
29
29
|
stringify as stringify2
|
|
30
30
|
} from "@liveblocks/core";
|
|
31
31
|
import * as React3 from "react";
|
|
32
|
-
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector.js";
|
|
32
|
+
import { useSyncExternalStoreWithSelector as useSyncExternalStoreWithSelector2 } from "use-sync-external-store/shim/with-selector.js";
|
|
33
33
|
|
|
34
34
|
// src/comments/CommentsRoom.tsx
|
|
35
35
|
import { CommentsApiError, makeEventSource, stringify } from "@liveblocks/core";
|
|
36
36
|
import { nanoid } from "nanoid";
|
|
37
37
|
import React2, {
|
|
38
38
|
createContext,
|
|
39
|
-
useCallback as
|
|
39
|
+
useCallback as useCallback2,
|
|
40
40
|
useContext,
|
|
41
41
|
useEffect as useEffect3,
|
|
42
|
-
useMemo
|
|
43
|
-
useRef as useRef3
|
|
42
|
+
useMemo
|
|
44
43
|
} from "react";
|
|
45
|
-
import {
|
|
44
|
+
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector.js";
|
|
46
45
|
|
|
47
46
|
// src/comments/errors.ts
|
|
48
47
|
var CreateThreadError = class extends Error {
|
|
@@ -103,66 +102,19 @@ var RemoveReactionError = class extends Error {
|
|
|
103
102
|
};
|
|
104
103
|
|
|
105
104
|
// src/comments/lib/revalidation.ts
|
|
106
|
-
import { useCallback
|
|
107
|
-
|
|
108
|
-
// src/comments/lib/use-is-document-visible.ts
|
|
109
|
-
import { useSyncExternalStore } from "use-sync-external-store/shim/index.js";
|
|
110
|
-
function useIsDocumentVisible() {
|
|
111
|
-
const isVisible = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
112
|
-
return isVisible;
|
|
113
|
-
}
|
|
114
|
-
function subscribe(onStoreChange) {
|
|
115
|
-
document.addEventListener("visibilitychange", onStoreChange);
|
|
116
|
-
return () => {
|
|
117
|
-
document.removeEventListener("visibilitychange", onStoreChange);
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
function getSnapshot() {
|
|
121
|
-
const isDocumentDefined = typeof document !== "undefined";
|
|
122
|
-
return isDocumentDefined ? document.visibilityState === "visible" : true;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// src/comments/lib/use-is-online.ts
|
|
126
|
-
import { useCallback, useRef } from "react";
|
|
127
|
-
import { useSyncExternalStore as useSyncExternalStore2 } from "use-sync-external-store/shim/index.js";
|
|
128
|
-
function useIsOnline() {
|
|
129
|
-
const isOnlineRef = useRef(true);
|
|
130
|
-
const subscribe2 = useCallback((onStoreChange) => {
|
|
131
|
-
function handleIsOnline() {
|
|
132
|
-
isOnlineRef.current = true;
|
|
133
|
-
onStoreChange();
|
|
134
|
-
}
|
|
135
|
-
function handleIsOffline() {
|
|
136
|
-
isOnlineRef.current = false;
|
|
137
|
-
onStoreChange();
|
|
138
|
-
}
|
|
139
|
-
window.addEventListener("online", handleIsOnline);
|
|
140
|
-
window.addEventListener("offline", handleIsOffline);
|
|
141
|
-
return () => {
|
|
142
|
-
window.removeEventListener("online", handleIsOnline);
|
|
143
|
-
window.removeEventListener("offline", handleIsOffline);
|
|
144
|
-
};
|
|
145
|
-
}, []);
|
|
146
|
-
const getSnapshot2 = useCallback(() => {
|
|
147
|
-
return isOnlineRef.current;
|
|
148
|
-
}, []);
|
|
149
|
-
const isOnline = useSyncExternalStore2(subscribe2, getSnapshot2, getSnapshot2);
|
|
150
|
-
return isOnline;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// src/comments/lib/revalidation.ts
|
|
105
|
+
import { useCallback, useEffect as useEffect2, useRef } from "react";
|
|
154
106
|
var DEFAULT_ERROR_RETRY_INTERVAL = 5e3;
|
|
155
107
|
var DEFAULT_MAX_ERROR_RETRY_COUNT = 5;
|
|
156
108
|
var DEFAULT_DEDUPING_INTERVAL = 2e3;
|
|
157
109
|
var timestamp = 0;
|
|
158
110
|
function useRevalidateCache(manager, fetcher, options = {}) {
|
|
159
|
-
const isOnlineRef =
|
|
111
|
+
const isOnlineRef = useRef(true);
|
|
160
112
|
const {
|
|
161
113
|
dedupingInterval = DEFAULT_DEDUPING_INTERVAL,
|
|
162
114
|
errorRetryInterval = DEFAULT_ERROR_RETRY_INTERVAL,
|
|
163
115
|
errorRetryCount = DEFAULT_MAX_ERROR_RETRY_COUNT
|
|
164
116
|
} = options;
|
|
165
|
-
const _revalidateCache =
|
|
117
|
+
const _revalidateCache = useCallback(
|
|
166
118
|
async ({
|
|
167
119
|
shouldDedupe,
|
|
168
120
|
retryCount = 0
|
|
@@ -237,7 +189,7 @@ function useRevalidateCache(manager, fetcher, options = {}) {
|
|
|
237
189
|
window.removeEventListener("offline", handleIsOffline);
|
|
238
190
|
};
|
|
239
191
|
}, []);
|
|
240
|
-
const revalidateCache =
|
|
192
|
+
const revalidateCache = useCallback(
|
|
241
193
|
({ shouldDedupe }) => {
|
|
242
194
|
return _revalidateCache({ shouldDedupe, retryCount: 0 });
|
|
243
195
|
},
|
|
@@ -246,7 +198,7 @@ function useRevalidateCache(manager, fetcher, options = {}) {
|
|
|
246
198
|
return revalidateCache;
|
|
247
199
|
}
|
|
248
200
|
function useMutate(manager, revalidateCache) {
|
|
249
|
-
const mutate =
|
|
201
|
+
const mutate = useCallback(
|
|
250
202
|
async (data, options) => {
|
|
251
203
|
const beforeMutationTimestamp = ++timestamp;
|
|
252
204
|
manager.setMutation({
|
|
@@ -283,122 +235,15 @@ function useMutate(manager, revalidateCache) {
|
|
|
283
235
|
);
|
|
284
236
|
return mutate;
|
|
285
237
|
}
|
|
286
|
-
function useAutomaticRevalidation(manager, revalidateCache, options = {}) {
|
|
287
|
-
const isOnline = useIsOnline();
|
|
288
|
-
const isDocumentVisible = useIsDocumentVisible();
|
|
289
|
-
const {
|
|
290
|
-
revalidateOnFocus = true,
|
|
291
|
-
revalidateOnReconnect = true,
|
|
292
|
-
refreshInterval = 0
|
|
293
|
-
} = options;
|
|
294
|
-
useEffect2(() => {
|
|
295
|
-
let revalidationTimerId;
|
|
296
|
-
function scheduleRevalidation() {
|
|
297
|
-
if (refreshInterval === 0)
|
|
298
|
-
return;
|
|
299
|
-
revalidationTimerId = window.setTimeout(() => {
|
|
300
|
-
if (isOnline && isDocumentVisible && !manager.getError()) {
|
|
301
|
-
void revalidateCache({ shouldDedupe: true }).then(
|
|
302
|
-
scheduleRevalidation
|
|
303
|
-
);
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
scheduleRevalidation();
|
|
307
|
-
}, refreshInterval);
|
|
308
|
-
}
|
|
309
|
-
scheduleRevalidation();
|
|
310
|
-
return () => {
|
|
311
|
-
window.clearTimeout(revalidationTimerId);
|
|
312
|
-
};
|
|
313
|
-
}, [revalidateCache, refreshInterval, isOnline, isDocumentVisible, manager]);
|
|
314
|
-
useEffect2(() => {
|
|
315
|
-
function handleIsOnline() {
|
|
316
|
-
if (revalidateOnReconnect && isDocumentVisible) {
|
|
317
|
-
void revalidateCache({ shouldDedupe: true });
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
window.addEventListener("online", handleIsOnline);
|
|
321
|
-
return () => {
|
|
322
|
-
window.removeEventListener("online", handleIsOnline);
|
|
323
|
-
};
|
|
324
|
-
}, [revalidateCache, revalidateOnReconnect, isDocumentVisible]);
|
|
325
|
-
useEffect2(() => {
|
|
326
|
-
function handleVisibilityChange() {
|
|
327
|
-
const isVisible = document.visibilityState === "visible";
|
|
328
|
-
if (revalidateOnFocus && isVisible && isOnline) {
|
|
329
|
-
void revalidateCache({ shouldDedupe: true });
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
333
|
-
return () => {
|
|
334
|
-
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
335
|
-
};
|
|
336
|
-
}, [revalidateCache, revalidateOnFocus, isOnline]);
|
|
337
|
-
}
|
|
338
238
|
|
|
339
239
|
// src/comments/CommentsRoom.tsx
|
|
340
|
-
var POLLING_INTERVAL_REALTIME = 3e4;
|
|
341
|
-
var POLLING_INTERVAL = 5e3;
|
|
342
240
|
var THREAD_ID_PREFIX = "th";
|
|
343
241
|
var COMMENT_ID_PREFIX = "cm";
|
|
344
242
|
function createCommentsRoom(errorEventSource) {
|
|
345
|
-
const
|
|
346
|
-
const filterOptions = /* @__PURE__ */ new Map();
|
|
347
|
-
const cacheStates = /* @__PURE__ */ new Map();
|
|
348
|
-
const revalidationManagers = /* @__PURE__ */ new Map();
|
|
349
|
-
function createThreadsRevalidationManager(key) {
|
|
350
|
-
let request;
|
|
351
|
-
let error;
|
|
352
|
-
return {
|
|
353
|
-
getCache() {
|
|
354
|
-
return void 0;
|
|
355
|
-
},
|
|
356
|
-
setCache(value) {
|
|
357
|
-
const cache = new Map(
|
|
358
|
-
(manager.getCache() ?? []).map((thread) => [thread.id, thread])
|
|
359
|
-
);
|
|
360
|
-
for (const thread of value) {
|
|
361
|
-
cache.set(thread.id, thread);
|
|
362
|
-
}
|
|
363
|
-
setCache(key, {
|
|
364
|
-
isLoading: false,
|
|
365
|
-
data: value
|
|
366
|
-
});
|
|
367
|
-
manager.setCache(Array.from(cache.values()));
|
|
368
|
-
},
|
|
369
|
-
// Request
|
|
370
|
-
getRequest() {
|
|
371
|
-
return request;
|
|
372
|
-
},
|
|
373
|
-
setRequest(value) {
|
|
374
|
-
request = value;
|
|
375
|
-
},
|
|
376
|
-
// Error
|
|
377
|
-
getError() {
|
|
378
|
-
return error;
|
|
379
|
-
},
|
|
380
|
-
setError(err) {
|
|
381
|
-
error = err;
|
|
382
|
-
manager.setError(err);
|
|
383
|
-
},
|
|
384
|
-
// Mutation
|
|
385
|
-
getMutation() {
|
|
386
|
-
return void 0;
|
|
387
|
-
},
|
|
388
|
-
setMutation() {
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
const eventSource = makeEventSource();
|
|
393
|
-
const subscribe2 = eventSource.subscribe;
|
|
394
|
-
const getCache = (key) => cacheStates.get(key);
|
|
395
|
-
const setCache = (key, value) => {
|
|
396
|
-
cacheStates.set(key, value);
|
|
397
|
-
};
|
|
243
|
+
const store = createClientCacheStore();
|
|
398
244
|
const FetcherContext = createContext(null);
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
function getThreads() {
|
|
245
|
+
const RoomManagerContext = createContext(null);
|
|
246
|
+
function getThreads(manager) {
|
|
402
247
|
const threads = manager.getCache();
|
|
403
248
|
if (!threads) {
|
|
404
249
|
throw new Error(
|
|
@@ -411,84 +256,54 @@ function createCommentsRoom(errorEventSource) {
|
|
|
411
256
|
room,
|
|
412
257
|
children
|
|
413
258
|
}) {
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
259
|
+
const manager = useMemo(() => {
|
|
260
|
+
return createRoomRevalidationManager(room.id, {
|
|
261
|
+
getCache: store.getThreads,
|
|
262
|
+
setCache: store.setThreads
|
|
263
|
+
});
|
|
264
|
+
}, [room.id]);
|
|
265
|
+
const fetcher = React2.useCallback(async () => {
|
|
266
|
+
const options = manager.getRevalidationManagers().filter(([key]) => manager.getReferenceCount(key) > 0).map(([_, manager2]) => manager2.getOptions());
|
|
417
267
|
const responses = await Promise.all(
|
|
418
|
-
|
|
419
|
-
return room.getThreads(
|
|
268
|
+
options.map(async (option) => {
|
|
269
|
+
return await room.getThreads(option);
|
|
420
270
|
})
|
|
421
271
|
);
|
|
422
272
|
const threads = Array.from(
|
|
423
273
|
new Map(responses.flat().map((thread) => [thread.id, thread])).values()
|
|
424
274
|
);
|
|
425
275
|
return threads;
|
|
426
|
-
}, [room]);
|
|
276
|
+
}, [room, manager]);
|
|
427
277
|
const revalidateCache = useRevalidateCache(manager, fetcher);
|
|
428
|
-
const subscribeToCommentEvents = useCallback3(() => {
|
|
429
|
-
const commentsEventSubscribersCount = commentsEventSubscribersCountRef.current;
|
|
430
|
-
if (commentsEventSubscribersCount === 0) {
|
|
431
|
-
const unsubscribe = room.events.comments.subscribe(() => {
|
|
432
|
-
void revalidateCache({ shouldDedupe: true });
|
|
433
|
-
});
|
|
434
|
-
commentsEventDisposerRef.current = unsubscribe;
|
|
435
|
-
}
|
|
436
|
-
commentsEventSubscribersCountRef.current = commentsEventSubscribersCount + 1;
|
|
437
|
-
return () => {
|
|
438
|
-
commentsEventSubscribersCountRef.current = commentsEventSubscribersCountRef.current - 1;
|
|
439
|
-
if (commentsEventSubscribersCountRef.current > 0)
|
|
440
|
-
return;
|
|
441
|
-
commentsEventDisposerRef.current?.();
|
|
442
|
-
commentsEventDisposerRef.current = void 0;
|
|
443
|
-
};
|
|
444
|
-
}, [revalidateCache, room]);
|
|
445
278
|
useEffect3(() => {
|
|
446
|
-
const unsubscribe =
|
|
447
|
-
|
|
448
|
-
const filtered = threads.filter((thread) => {
|
|
449
|
-
const query = info.options.query;
|
|
450
|
-
if (!query)
|
|
451
|
-
return true;
|
|
452
|
-
for (const key2 in query.metadata) {
|
|
453
|
-
if (thread.metadata[key2] !== query.metadata[key2]) {
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
return true;
|
|
458
|
-
});
|
|
459
|
-
setCache(key, {
|
|
460
|
-
isLoading: false,
|
|
461
|
-
data: filtered
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
for (const [key] of cacheStates.entries()) {
|
|
465
|
-
if (filterOptions.has(key))
|
|
466
|
-
continue;
|
|
467
|
-
cacheStates.delete(key);
|
|
468
|
-
}
|
|
469
|
-
eventSource.notify(threads);
|
|
279
|
+
const unsubscribe = room.events.comments.subscribe(() => {
|
|
280
|
+
void revalidateCache({ shouldDedupe: false });
|
|
470
281
|
});
|
|
471
282
|
return () => {
|
|
472
283
|
unsubscribe();
|
|
473
284
|
};
|
|
474
|
-
}, []);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
285
|
+
}, [room, revalidateCache]);
|
|
286
|
+
return /* @__PURE__ */ React2.createElement(FetcherContext.Provider, { value: fetcher }, /* @__PURE__ */ React2.createElement(RoomManagerContext.Provider, { value: manager }, children));
|
|
287
|
+
}
|
|
288
|
+
function useRoomManager() {
|
|
289
|
+
const manager = useContext(RoomManagerContext);
|
|
290
|
+
if (manager === null) {
|
|
291
|
+
throw new Error("CommentsRoomProvider is missing from the React tree.");
|
|
292
|
+
}
|
|
293
|
+
return manager;
|
|
294
|
+
}
|
|
295
|
+
function getUseThreadsRevalidationManager(options, roomManager) {
|
|
296
|
+
const key = stringify(options);
|
|
297
|
+
const revalidationManager = roomManager.getRevalidationManager(key);
|
|
298
|
+
if (!revalidationManager) {
|
|
299
|
+
const useThreadsRevalidationManager = createUseThreadsRevalidationManager(
|
|
300
|
+
options,
|
|
301
|
+
roomManager
|
|
302
|
+
);
|
|
303
|
+
roomManager.setRevalidationmanager(key, useThreadsRevalidationManager);
|
|
304
|
+
return useThreadsRevalidationManager;
|
|
305
|
+
}
|
|
306
|
+
return revalidationManager;
|
|
492
307
|
}
|
|
493
308
|
function useThreadsFetcher() {
|
|
494
309
|
const fetcher = useContext(FetcherContext);
|
|
@@ -497,156 +312,147 @@ function createCommentsRoom(errorEventSource) {
|
|
|
497
312
|
}
|
|
498
313
|
return fetcher;
|
|
499
314
|
}
|
|
500
|
-
function _useThreads(room, key) {
|
|
501
|
-
const fetcher = useThreadsFetcher();
|
|
502
|
-
const revalidateCache = useRevalidateCache(manager, fetcher);
|
|
503
|
-
const status = useSyncExternalStore3(
|
|
504
|
-
room.events.status.subscribe,
|
|
505
|
-
room.getStatus,
|
|
506
|
-
room.getStatus
|
|
507
|
-
);
|
|
508
|
-
const isOnline = useIsOnline();
|
|
509
|
-
const isDocumentVisible = useIsDocumentVisible();
|
|
510
|
-
const subscribeToCommentEvents = useContext(
|
|
511
|
-
CommentsEventSubscriptionContext
|
|
512
|
-
);
|
|
513
|
-
const interval = getPollingInterval(
|
|
514
|
-
isOnline,
|
|
515
|
-
isDocumentVisible,
|
|
516
|
-
status === "connected"
|
|
517
|
-
);
|
|
518
|
-
useAutomaticRevalidation(manager, revalidateCache, {
|
|
519
|
-
revalidateOnFocus: true,
|
|
520
|
-
revalidateOnReconnect: true,
|
|
521
|
-
refreshInterval: interval
|
|
522
|
-
});
|
|
523
|
-
useEffect3(subscribeToCommentEvents, [subscribeToCommentEvents]);
|
|
524
|
-
const cache = useSyncExternalStore3(
|
|
525
|
-
subscribe2,
|
|
526
|
-
() => getCache(key),
|
|
527
|
-
() => getCache(key)
|
|
528
|
-
);
|
|
529
|
-
if (!cache || cache.isLoading) {
|
|
530
|
-
return { isLoading: true };
|
|
531
|
-
}
|
|
532
|
-
return {
|
|
533
|
-
isLoading: cache.isLoading,
|
|
534
|
-
threads: cache.data || [],
|
|
535
|
-
error: cache.error
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
315
|
function useThreads(room, options = { query: { metadata: {} } }) {
|
|
539
316
|
const key = useMemo(() => stringify(options), [options]);
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
const fetcher =
|
|
317
|
+
const manager = useRoomManager();
|
|
318
|
+
const useThreadsRevalidationManager = getUseThreadsRevalidationManager(
|
|
319
|
+
options,
|
|
320
|
+
manager
|
|
321
|
+
);
|
|
322
|
+
const fetcher = React2.useCallback(
|
|
546
323
|
() => {
|
|
547
324
|
return room.getThreads(options);
|
|
548
325
|
},
|
|
549
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
550
|
-
[key]
|
|
326
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- The missing dependency is `options` but `key` and `normalized` are analogous, so we only include `key` as dependency. This helps minimize the number of re-renders as `options` can change on each render
|
|
327
|
+
[key, room]
|
|
551
328
|
);
|
|
552
|
-
const revalidateCache = useRevalidateCache(
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
const info = filterOptions.get(key);
|
|
556
|
-
if (info) {
|
|
557
|
-
info.count += 1;
|
|
558
|
-
} else {
|
|
559
|
-
filterOptions.set(key, {
|
|
560
|
-
options,
|
|
561
|
-
count: 1
|
|
562
|
-
});
|
|
563
|
-
cacheStates.set(key, { isLoading: true });
|
|
564
|
-
}
|
|
565
|
-
return () => {
|
|
566
|
-
const info2 = filterOptions.get(key);
|
|
567
|
-
if (!info2)
|
|
568
|
-
return;
|
|
569
|
-
info2.count -= 1;
|
|
570
|
-
if (info2.count > 0)
|
|
571
|
-
return;
|
|
572
|
-
filterOptions.delete(key);
|
|
573
|
-
};
|
|
574
|
-
},
|
|
575
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
576
|
-
[key]
|
|
329
|
+
const revalidateCache = useRevalidateCache(
|
|
330
|
+
useThreadsRevalidationManager,
|
|
331
|
+
fetcher
|
|
577
332
|
);
|
|
578
333
|
useEffect3(() => {
|
|
579
334
|
void revalidateCache({ shouldDedupe: true });
|
|
580
335
|
}, [revalidateCache]);
|
|
581
|
-
|
|
336
|
+
useEffect3(() => {
|
|
337
|
+
manager.incrementReferenceCount(key);
|
|
338
|
+
return () => {
|
|
339
|
+
manager.decrementReferenceCount(key);
|
|
340
|
+
};
|
|
341
|
+
});
|
|
342
|
+
return useSyncExternalStoreWithSelector(
|
|
343
|
+
store.subscribe,
|
|
344
|
+
() => store.getThreads(),
|
|
345
|
+
() => store.getThreads(),
|
|
346
|
+
(state) => {
|
|
347
|
+
const isLoading = useThreadsRevalidationManager.getIsLoading();
|
|
348
|
+
if (isLoading) {
|
|
349
|
+
return {
|
|
350
|
+
isLoading: true
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
const options2 = useThreadsRevalidationManager.getOptions();
|
|
354
|
+
const error = useThreadsRevalidationManager.getError();
|
|
355
|
+
const filtered = state.filter((thread) => {
|
|
356
|
+
if (thread.roomId !== room.id)
|
|
357
|
+
return false;
|
|
358
|
+
const query = options2.query ?? {};
|
|
359
|
+
for (const key2 in query.metadata) {
|
|
360
|
+
if (thread.metadata[key2] !== query.metadata[key2]) {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return true;
|
|
365
|
+
});
|
|
366
|
+
return {
|
|
367
|
+
isLoading: false,
|
|
368
|
+
threads: filtered,
|
|
369
|
+
error
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
);
|
|
582
373
|
}
|
|
583
|
-
function useThreadsSuspense(room, options = {}) {
|
|
374
|
+
function useThreadsSuspense(room, options = { query: { metadata: {} } }) {
|
|
584
375
|
const key = useMemo(() => stringify(options), [options]);
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
const fetcher =
|
|
376
|
+
const manager = useRoomManager();
|
|
377
|
+
const useThreadsRevalidationManager = getUseThreadsRevalidationManager(
|
|
378
|
+
options,
|
|
379
|
+
manager
|
|
380
|
+
);
|
|
381
|
+
const fetcher = React2.useCallback(
|
|
591
382
|
() => {
|
|
592
383
|
return room.getThreads(options);
|
|
593
384
|
},
|
|
594
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
595
|
-
[key]
|
|
385
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- The missing dependency is `options` but `key` and `normalized` are analogous, so we only include `key` as dependency. This helps minimize the number of re-renders as `options` can change on each render
|
|
386
|
+
[key, room]
|
|
596
387
|
);
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
388
|
+
const revalidateCache = useRevalidateCache(
|
|
389
|
+
useThreadsRevalidationManager,
|
|
390
|
+
fetcher
|
|
391
|
+
);
|
|
392
|
+
useEffect3(() => {
|
|
393
|
+
void revalidateCache({ shouldDedupe: true });
|
|
394
|
+
}, [revalidateCache]);
|
|
395
|
+
useEffect3(() => {
|
|
396
|
+
manager.incrementReferenceCount(key);
|
|
397
|
+
return () => {
|
|
398
|
+
manager.decrementReferenceCount(key);
|
|
399
|
+
};
|
|
400
|
+
});
|
|
401
|
+
const cache = useSyncExternalStoreWithSelector(
|
|
402
|
+
store.subscribe,
|
|
403
|
+
() => store.getThreads(),
|
|
404
|
+
() => store.getThreads(),
|
|
405
|
+
(state) => {
|
|
406
|
+
const isLoading = useThreadsRevalidationManager.getIsLoading();
|
|
407
|
+
if (isLoading) {
|
|
408
|
+
return {
|
|
409
|
+
isLoading: true
|
|
410
|
+
};
|
|
616
411
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
412
|
+
const options2 = useThreadsRevalidationManager.getOptions();
|
|
413
|
+
const error = useThreadsRevalidationManager.getError();
|
|
414
|
+
const filtered = state.filter((thread) => {
|
|
415
|
+
if (thread.roomId !== room.id)
|
|
416
|
+
return false;
|
|
417
|
+
const query = options2.query ?? {};
|
|
418
|
+
for (const key2 in query.metadata) {
|
|
419
|
+
if (thread.metadata[key2] !== query.metadata[key2]) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return true;
|
|
424
|
+
});
|
|
425
|
+
return {
|
|
426
|
+
isLoading: false,
|
|
427
|
+
threads: filtered,
|
|
428
|
+
error
|
|
625
429
|
};
|
|
626
|
-
}
|
|
627
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
628
|
-
[key]
|
|
430
|
+
}
|
|
629
431
|
);
|
|
630
|
-
const cache = _useThreads(room, key);
|
|
631
432
|
if (cache.error) {
|
|
632
433
|
throw cache.error;
|
|
633
434
|
}
|
|
634
435
|
if (cache.isLoading || !cache.threads) {
|
|
635
|
-
throw revalidateCache({
|
|
436
|
+
throw revalidateCache({
|
|
437
|
+
shouldDedupe: true
|
|
438
|
+
});
|
|
636
439
|
}
|
|
637
440
|
return {
|
|
441
|
+
isLoading: false,
|
|
638
442
|
threads: cache.threads,
|
|
639
|
-
|
|
443
|
+
error: cache.error
|
|
640
444
|
};
|
|
641
445
|
}
|
|
642
446
|
function useEditThreadMetadata(room) {
|
|
643
|
-
const
|
|
447
|
+
const manager = useRoomManager();
|
|
448
|
+
const fetcher = useThreadsFetcher();
|
|
449
|
+
const revalidate = useRevalidateCache(manager, fetcher);
|
|
644
450
|
const mutate = useMutate(manager, revalidate);
|
|
645
|
-
const editThreadMetadata =
|
|
451
|
+
const editThreadMetadata = useCallback2(
|
|
646
452
|
(options) => {
|
|
647
453
|
const threadId = options.threadId;
|
|
648
454
|
const metadata = "metadata" in options ? options.metadata : {};
|
|
649
|
-
const threads = getThreads();
|
|
455
|
+
const threads = getThreads(manager);
|
|
650
456
|
const optimisticData = threads.map(
|
|
651
457
|
(thread) => thread.id === threadId ? {
|
|
652
458
|
...thread,
|
|
@@ -672,19 +478,20 @@ function createCommentsRoom(errorEventSource) {
|
|
|
672
478
|
);
|
|
673
479
|
});
|
|
674
480
|
},
|
|
675
|
-
[room, mutate]
|
|
481
|
+
[room, mutate, manager]
|
|
676
482
|
);
|
|
677
483
|
return editThreadMetadata;
|
|
678
484
|
}
|
|
679
485
|
function useCreateThread(room) {
|
|
486
|
+
const manager = useRoomManager();
|
|
680
487
|
const fetcher = useThreadsFetcher();
|
|
681
488
|
const revalidate = useRevalidateCache(manager, fetcher);
|
|
682
489
|
const mutate = useMutate(manager, revalidate);
|
|
683
|
-
const createThread =
|
|
490
|
+
const createThread = useCallback2(
|
|
684
491
|
(options) => {
|
|
685
492
|
const body = options.body;
|
|
686
493
|
const metadata = "metadata" in options ? options.metadata : {};
|
|
687
|
-
const threads = getThreads();
|
|
494
|
+
const threads = getThreads(manager);
|
|
688
495
|
const threadId = createOptimisticId(THREAD_ID_PREFIX);
|
|
689
496
|
const commentId = createOptimisticId(COMMENT_ID_PREFIX);
|
|
690
497
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -725,17 +532,18 @@ function createCommentsRoom(errorEventSource) {
|
|
|
725
532
|
});
|
|
726
533
|
return newThread;
|
|
727
534
|
},
|
|
728
|
-
[room, mutate]
|
|
535
|
+
[room, mutate, manager]
|
|
729
536
|
);
|
|
730
537
|
return createThread;
|
|
731
538
|
}
|
|
732
539
|
function useCreateComment(room) {
|
|
540
|
+
const manager = useRoomManager();
|
|
733
541
|
const fetcher = useThreadsFetcher();
|
|
734
542
|
const revalidate = useRevalidateCache(manager, fetcher);
|
|
735
543
|
const mutate = useMutate(manager, revalidate);
|
|
736
|
-
const createComment =
|
|
544
|
+
const createComment = useCallback2(
|
|
737
545
|
({ threadId, body }) => {
|
|
738
|
-
const threads = getThreads();
|
|
546
|
+
const threads = getThreads(manager);
|
|
739
547
|
const commentId = createOptimisticId(COMMENT_ID_PREFIX);
|
|
740
548
|
const now = /* @__PURE__ */ new Date();
|
|
741
549
|
const comment = {
|
|
@@ -772,16 +580,18 @@ function createCommentsRoom(errorEventSource) {
|
|
|
772
580
|
});
|
|
773
581
|
return comment;
|
|
774
582
|
},
|
|
775
|
-
[room, mutate]
|
|
583
|
+
[room, mutate, manager]
|
|
776
584
|
);
|
|
777
585
|
return createComment;
|
|
778
586
|
}
|
|
779
587
|
function useEditComment(room) {
|
|
780
|
-
const
|
|
588
|
+
const manager = useRoomManager();
|
|
589
|
+
const fetcher = useThreadsFetcher();
|
|
590
|
+
const revalidate = useRevalidateCache(manager, fetcher);
|
|
781
591
|
const mutate = useMutate(manager, revalidate);
|
|
782
|
-
const editComment =
|
|
592
|
+
const editComment = useCallback2(
|
|
783
593
|
({ threadId, commentId, body }) => {
|
|
784
|
-
const threads = getThreads();
|
|
594
|
+
const threads = getThreads(manager);
|
|
785
595
|
const now = /* @__PURE__ */ new Date();
|
|
786
596
|
const optimisticData = threads.map(
|
|
787
597
|
(thread) => thread.id === threadId ? {
|
|
@@ -812,16 +622,18 @@ function createCommentsRoom(errorEventSource) {
|
|
|
812
622
|
);
|
|
813
623
|
});
|
|
814
624
|
},
|
|
815
|
-
[room, mutate]
|
|
625
|
+
[room, mutate, manager]
|
|
816
626
|
);
|
|
817
627
|
return editComment;
|
|
818
628
|
}
|
|
819
629
|
function useDeleteComment(room) {
|
|
820
|
-
const
|
|
630
|
+
const manager = useRoomManager();
|
|
631
|
+
const fetcher = useThreadsFetcher();
|
|
632
|
+
const revalidate = useRevalidateCache(manager, fetcher);
|
|
821
633
|
const mutate = useMutate(manager, revalidate);
|
|
822
|
-
const deleteComment =
|
|
634
|
+
const deleteComment = useCallback2(
|
|
823
635
|
({ threadId, commentId }) => {
|
|
824
|
-
const threads = getThreads();
|
|
636
|
+
const threads = getThreads(manager);
|
|
825
637
|
const now = /* @__PURE__ */ new Date();
|
|
826
638
|
const newThreads = [];
|
|
827
639
|
for (const thread of threads) {
|
|
@@ -861,16 +673,18 @@ function createCommentsRoom(errorEventSource) {
|
|
|
861
673
|
);
|
|
862
674
|
});
|
|
863
675
|
},
|
|
864
|
-
[room, mutate]
|
|
676
|
+
[room, mutate, manager]
|
|
865
677
|
);
|
|
866
678
|
return deleteComment;
|
|
867
679
|
}
|
|
868
680
|
function useAddReaction(room) {
|
|
869
|
-
const
|
|
681
|
+
const manager = useRoomManager();
|
|
682
|
+
const fetcher = useThreadsFetcher();
|
|
683
|
+
const revalidate = useRevalidateCache(manager, fetcher);
|
|
870
684
|
const mutate = useMutate(manager, revalidate);
|
|
871
|
-
const createComment =
|
|
685
|
+
const createComment = useCallback2(
|
|
872
686
|
({ threadId, commentId, emoji }) => {
|
|
873
|
-
const threads = getThreads();
|
|
687
|
+
const threads = getThreads(manager);
|
|
874
688
|
const now = /* @__PURE__ */ new Date();
|
|
875
689
|
const userId = getCurrentUserId(room);
|
|
876
690
|
const optimisticData = threads.map(
|
|
@@ -924,16 +738,18 @@ function createCommentsRoom(errorEventSource) {
|
|
|
924
738
|
);
|
|
925
739
|
});
|
|
926
740
|
},
|
|
927
|
-
[room, mutate]
|
|
741
|
+
[room, mutate, manager]
|
|
928
742
|
);
|
|
929
743
|
return createComment;
|
|
930
744
|
}
|
|
931
745
|
function useRemoveReaction(room) {
|
|
932
|
-
const
|
|
746
|
+
const manager = useRoomManager();
|
|
747
|
+
const fetcher = useThreadsFetcher();
|
|
748
|
+
const revalidate = useRevalidateCache(manager, fetcher);
|
|
933
749
|
const mutate = useMutate(manager, revalidate);
|
|
934
|
-
const createComment =
|
|
750
|
+
const createComment = useCallback2(
|
|
935
751
|
({ threadId, commentId, emoji }) => {
|
|
936
|
-
const threads = getThreads();
|
|
752
|
+
const threads = getThreads(manager);
|
|
937
753
|
const userId = getCurrentUserId(room);
|
|
938
754
|
const optimisticData = threads.map(
|
|
939
755
|
(thread) => thread.id === threadId ? {
|
|
@@ -985,7 +801,7 @@ function createCommentsRoom(errorEventSource) {
|
|
|
985
801
|
);
|
|
986
802
|
});
|
|
987
803
|
},
|
|
988
|
-
[room, mutate]
|
|
804
|
+
[room, mutate, manager]
|
|
989
805
|
);
|
|
990
806
|
return createComment;
|
|
991
807
|
}
|
|
@@ -1021,31 +837,35 @@ function handleCommentsApiError(err) {
|
|
|
1021
837
|
}
|
|
1022
838
|
return new Error(message);
|
|
1023
839
|
}
|
|
1024
|
-
function
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
return POLLING_INTERVAL_REALTIME;
|
|
1029
|
-
return POLLING_INTERVAL;
|
|
1030
|
-
}
|
|
1031
|
-
function createThreadsCacheManager() {
|
|
1032
|
-
let cache;
|
|
840
|
+
function createRoomRevalidationManager(roomId, {
|
|
841
|
+
getCache,
|
|
842
|
+
setCache
|
|
843
|
+
}) {
|
|
1033
844
|
let request;
|
|
1034
845
|
let error;
|
|
1035
846
|
let mutation;
|
|
1036
|
-
const
|
|
1037
|
-
const
|
|
847
|
+
const revalidationManagerByOptions = /* @__PURE__ */ new Map();
|
|
848
|
+
const referenceCountByOptions = /* @__PURE__ */ new Map();
|
|
1038
849
|
return {
|
|
1039
850
|
// Cache
|
|
1040
851
|
getCache() {
|
|
1041
|
-
|
|
852
|
+
const threads = getCache();
|
|
853
|
+
const filtered = threads.filter((thread) => thread.roomId === roomId);
|
|
854
|
+
return filtered;
|
|
1042
855
|
},
|
|
1043
856
|
setCache(value) {
|
|
857
|
+
for (const key of revalidationManagerByOptions.keys()) {
|
|
858
|
+
if (referenceCountByOptions.get(key) === 0) {
|
|
859
|
+
revalidationManagerByOptions.delete(key);
|
|
860
|
+
referenceCountByOptions.delete(key);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
1044
863
|
const sorted = value.sort(
|
|
1045
864
|
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
|
1046
865
|
);
|
|
1047
|
-
|
|
1048
|
-
|
|
866
|
+
const threads = getCache();
|
|
867
|
+
const newThreads = threads.filter((thread) => thread.roomId !== roomId).concat(sorted);
|
|
868
|
+
setCache(newThreads);
|
|
1049
869
|
},
|
|
1050
870
|
// Request
|
|
1051
871
|
getRequest() {
|
|
@@ -1060,7 +880,6 @@ function createThreadsCacheManager() {
|
|
|
1060
880
|
},
|
|
1061
881
|
setError(err) {
|
|
1062
882
|
error = err;
|
|
1063
|
-
errorEventSource.notify(err);
|
|
1064
883
|
},
|
|
1065
884
|
// Mutation
|
|
1066
885
|
getMutation() {
|
|
@@ -1069,25 +888,103 @@ function createThreadsCacheManager() {
|
|
|
1069
888
|
setMutation(info) {
|
|
1070
889
|
mutation = info;
|
|
1071
890
|
},
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
891
|
+
getRevalidationManagers() {
|
|
892
|
+
return Array.from(revalidationManagerByOptions.entries());
|
|
893
|
+
},
|
|
894
|
+
getRevalidationManager(key) {
|
|
895
|
+
return revalidationManagerByOptions.get(key);
|
|
896
|
+
},
|
|
897
|
+
setRevalidationmanager(key, manager) {
|
|
898
|
+
revalidationManagerByOptions.set(key, manager);
|
|
899
|
+
},
|
|
900
|
+
incrementReferenceCount(key) {
|
|
901
|
+
const count = referenceCountByOptions.get(key) ?? 0;
|
|
902
|
+
referenceCountByOptions.set(key, count + 1);
|
|
903
|
+
},
|
|
904
|
+
decrementReferenceCount(key) {
|
|
905
|
+
const count = referenceCountByOptions.get(key) ?? 0;
|
|
906
|
+
referenceCountByOptions.set(key, count - 1);
|
|
907
|
+
},
|
|
908
|
+
getReferenceCount(key) {
|
|
909
|
+
return referenceCountByOptions.get(key) ?? 0;
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
function createClientCacheStore() {
|
|
914
|
+
let threads = [];
|
|
915
|
+
const threadsEventSource = makeEventSource();
|
|
916
|
+
return {
|
|
917
|
+
getThreads() {
|
|
918
|
+
return threads;
|
|
919
|
+
},
|
|
920
|
+
setThreads(value) {
|
|
921
|
+
threads = value;
|
|
922
|
+
threadsEventSource.notify(threads);
|
|
923
|
+
},
|
|
924
|
+
subscribe(callback) {
|
|
925
|
+
return threadsEventSource.subscribe(callback);
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
function createUseThreadsRevalidationManager(options, manager) {
|
|
930
|
+
let isLoading = true;
|
|
931
|
+
let request;
|
|
932
|
+
let error;
|
|
933
|
+
const errorEventSource = makeEventSource();
|
|
934
|
+
return {
|
|
935
|
+
// Cache
|
|
936
|
+
getCache() {
|
|
937
|
+
return void 0;
|
|
938
|
+
},
|
|
939
|
+
setCache(value) {
|
|
940
|
+
const cache = new Map(
|
|
941
|
+
(manager.getCache() ?? []).map((thread) => [thread.id, thread])
|
|
942
|
+
);
|
|
943
|
+
for (const thread of value) {
|
|
944
|
+
cache.set(thread.id, thread);
|
|
1081
945
|
}
|
|
946
|
+
manager.setCache(Array.from(cache.values()));
|
|
947
|
+
isLoading = false;
|
|
948
|
+
},
|
|
949
|
+
// Request
|
|
950
|
+
getRequest() {
|
|
951
|
+
return request;
|
|
952
|
+
},
|
|
953
|
+
setRequest(value) {
|
|
954
|
+
request = value;
|
|
955
|
+
},
|
|
956
|
+
// Error
|
|
957
|
+
getError() {
|
|
958
|
+
return error;
|
|
959
|
+
},
|
|
960
|
+
setError(err) {
|
|
961
|
+
error = err;
|
|
962
|
+
errorEventSource.notify(err);
|
|
963
|
+
},
|
|
964
|
+
// Mutation
|
|
965
|
+
getMutation() {
|
|
966
|
+
return void 0;
|
|
967
|
+
},
|
|
968
|
+
setMutation(_) {
|
|
969
|
+
return;
|
|
970
|
+
},
|
|
971
|
+
getOptions() {
|
|
972
|
+
return options;
|
|
973
|
+
},
|
|
974
|
+
getIsLoading() {
|
|
975
|
+
return isLoading;
|
|
976
|
+
},
|
|
977
|
+
setIsLoading(value) {
|
|
978
|
+
isLoading = value;
|
|
1082
979
|
}
|
|
1083
980
|
};
|
|
1084
981
|
}
|
|
1085
982
|
|
|
1086
983
|
// src/comments/lib/use-debounce.ts
|
|
1087
|
-
import { useEffect as useEffect4, useRef as
|
|
984
|
+
import { useEffect as useEffect4, useRef as useRef2, useState as useState2 } from "react";
|
|
1088
985
|
var DEFAULT_DELAY = 500;
|
|
1089
986
|
function useDebounce(value, delay = DEFAULT_DELAY) {
|
|
1090
|
-
const timeout =
|
|
987
|
+
const timeout = useRef2();
|
|
1091
988
|
const [debouncedValue, setDebouncedValue] = useState2(value);
|
|
1092
989
|
useEffect4(() => {
|
|
1093
990
|
if (delay === false) {
|
|
@@ -1108,8 +1005,8 @@ function useDebounce(value, delay = DEFAULT_DELAY) {
|
|
|
1108
1005
|
}
|
|
1109
1006
|
|
|
1110
1007
|
// src/lib/use-async-cache.ts
|
|
1111
|
-
import { useCallback as
|
|
1112
|
-
import { useSyncExternalStore
|
|
1008
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo2, useRef as useRef3 } from "react";
|
|
1009
|
+
import { useSyncExternalStore } from "use-sync-external-store/shim/index.js";
|
|
1113
1010
|
|
|
1114
1011
|
// src/lib/use-initial.ts
|
|
1115
1012
|
import { useState as useState3 } from "react";
|
|
@@ -1135,17 +1032,17 @@ function useAsyncCache(cache, key, options) {
|
|
|
1135
1032
|
void cacheItem2.get();
|
|
1136
1033
|
return cacheItem2;
|
|
1137
1034
|
}, [cache, key]);
|
|
1138
|
-
const
|
|
1035
|
+
const subscribe = useCallback3(
|
|
1139
1036
|
(callback) => cacheItem?.subscribe(callback) ?? noop,
|
|
1140
1037
|
[cacheItem]
|
|
1141
1038
|
);
|
|
1142
|
-
const getState =
|
|
1039
|
+
const getState = useCallback3(
|
|
1143
1040
|
() => cacheItem?.getState() ?? INITIAL_ASYNC_STATE,
|
|
1144
1041
|
[cacheItem]
|
|
1145
1042
|
);
|
|
1146
|
-
const revalidate =
|
|
1147
|
-
const state =
|
|
1148
|
-
const previousData =
|
|
1043
|
+
const revalidate = useCallback3(() => cacheItem?.revalidate(), [cacheItem]);
|
|
1044
|
+
const state = useSyncExternalStore(subscribe, getState, getState);
|
|
1045
|
+
const previousData = useRef3();
|
|
1149
1046
|
let data = state.data;
|
|
1150
1047
|
useEffect5(() => {
|
|
1151
1048
|
previousData.current = { key, data: state.data };
|
|
@@ -1186,9 +1083,9 @@ function useAsyncCache(cache, key, options) {
|
|
|
1186
1083
|
}
|
|
1187
1084
|
|
|
1188
1085
|
// src/lib/use-latest.ts
|
|
1189
|
-
import { useEffect as useEffect6, useRef as
|
|
1086
|
+
import { useEffect as useEffect6, useRef as useRef4 } from "react";
|
|
1190
1087
|
function useLatest(value) {
|
|
1191
|
-
const ref =
|
|
1088
|
+
const ref = useRef4(value);
|
|
1192
1089
|
useEffect6(() => {
|
|
1193
1090
|
ref.current = value;
|
|
1194
1091
|
}, [value]);
|
|
@@ -1224,8 +1121,8 @@ var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\
|
|
|
1224
1121
|
|
|
1225
1122
|
Why? Please see https://liveblocks.io/docs/platform/troubleshooting#stale-props-zombie-child for more information`;
|
|
1226
1123
|
var superfluous_unstable_batchedUpdates = "You don\u2019t need to pass unstable_batchedUpdates to RoomProvider anymore, since you\u2019re on React 18+ already.";
|
|
1227
|
-
function
|
|
1228
|
-
return
|
|
1124
|
+
function useSyncExternalStore2(s, gs, gss) {
|
|
1125
|
+
return useSyncExternalStoreWithSelector2(s, gs, gss, identity);
|
|
1229
1126
|
}
|
|
1230
1127
|
var STABLE_EMPTY_LIST = Object.freeze([]);
|
|
1231
1128
|
function alwaysEmptyList() {
|
|
@@ -1373,16 +1270,16 @@ function createRoomContext(client, options) {
|
|
|
1373
1270
|
}
|
|
1374
1271
|
function useStatus() {
|
|
1375
1272
|
const room = useRoom();
|
|
1376
|
-
const
|
|
1377
|
-
const
|
|
1273
|
+
const subscribe = room.events.status.subscribe;
|
|
1274
|
+
const getSnapshot = room.getStatus;
|
|
1378
1275
|
const getServerSnapshot = room.getStatus;
|
|
1379
|
-
return
|
|
1276
|
+
return useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot);
|
|
1380
1277
|
}
|
|
1381
1278
|
function useMyPresence() {
|
|
1382
1279
|
const room = useRoom();
|
|
1383
|
-
const
|
|
1384
|
-
const
|
|
1385
|
-
const presence =
|
|
1280
|
+
const subscribe = room.events.myPresence.subscribe;
|
|
1281
|
+
const getSnapshot = room.getPresence;
|
|
1282
|
+
const presence = useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
|
|
1386
1283
|
const setPresence = room.updatePresence;
|
|
1387
1284
|
return [presence, setPresence];
|
|
1388
1285
|
}
|
|
@@ -1391,12 +1288,12 @@ function createRoomContext(client, options) {
|
|
|
1391
1288
|
}
|
|
1392
1289
|
function useOthers(selector, isEqual) {
|
|
1393
1290
|
const room = useRoom();
|
|
1394
|
-
const
|
|
1395
|
-
const
|
|
1291
|
+
const subscribe = room.events.others.subscribe;
|
|
1292
|
+
const getSnapshot = room.getOthers;
|
|
1396
1293
|
const getServerSnapshot = alwaysEmptyList;
|
|
1397
|
-
return
|
|
1398
|
-
|
|
1399
|
-
|
|
1294
|
+
return useSyncExternalStoreWithSelector2(
|
|
1295
|
+
subscribe,
|
|
1296
|
+
getSnapshot,
|
|
1400
1297
|
getServerSnapshot,
|
|
1401
1298
|
selector ?? identity,
|
|
1402
1299
|
isEqual
|
|
@@ -1500,17 +1397,17 @@ function createRoomContext(client, options) {
|
|
|
1500
1397
|
}
|
|
1501
1398
|
function useSelf(maybeSelector, isEqual) {
|
|
1502
1399
|
const room = useRoom();
|
|
1503
|
-
const
|
|
1504
|
-
const
|
|
1400
|
+
const subscribe = room.events.self.subscribe;
|
|
1401
|
+
const getSnapshot = room.getSelf;
|
|
1505
1402
|
const selector = maybeSelector ?? identity;
|
|
1506
1403
|
const wrappedSelector = React3.useCallback(
|
|
1507
1404
|
(me) => me !== null ? selector(me) : null,
|
|
1508
1405
|
[selector]
|
|
1509
1406
|
);
|
|
1510
1407
|
const getServerSnapshot = alwaysNull;
|
|
1511
|
-
return
|
|
1512
|
-
|
|
1513
|
-
|
|
1408
|
+
return useSyncExternalStoreWithSelector2(
|
|
1409
|
+
subscribe,
|
|
1410
|
+
getSnapshot,
|
|
1514
1411
|
getServerSnapshot,
|
|
1515
1412
|
wrappedSelector,
|
|
1516
1413
|
isEqual
|
|
@@ -1518,10 +1415,10 @@ function createRoomContext(client, options) {
|
|
|
1518
1415
|
}
|
|
1519
1416
|
function useMutableStorageRoot() {
|
|
1520
1417
|
const room = useRoom();
|
|
1521
|
-
const
|
|
1522
|
-
const
|
|
1418
|
+
const subscribe = room.events.storageDidLoad.subscribeOnce;
|
|
1419
|
+
const getSnapshot = room.getStorageSnapshot;
|
|
1523
1420
|
const getServerSnapshot = alwaysNull;
|
|
1524
|
-
return
|
|
1421
|
+
return useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot);
|
|
1525
1422
|
}
|
|
1526
1423
|
function useStorageRoot() {
|
|
1527
1424
|
return [useMutableStorageRoot()];
|
|
@@ -1537,15 +1434,15 @@ function createRoomContext(client, options) {
|
|
|
1537
1434
|
}
|
|
1538
1435
|
function useCanUndo() {
|
|
1539
1436
|
const room = useRoom();
|
|
1540
|
-
const
|
|
1437
|
+
const subscribe = room.events.history.subscribe;
|
|
1541
1438
|
const canUndo = room.history.canUndo;
|
|
1542
|
-
return
|
|
1439
|
+
return useSyncExternalStore2(subscribe, canUndo, canUndo);
|
|
1543
1440
|
}
|
|
1544
1441
|
function useCanRedo() {
|
|
1545
1442
|
const room = useRoom();
|
|
1546
|
-
const
|
|
1443
|
+
const subscribe = room.events.history.subscribe;
|
|
1547
1444
|
const canRedo = room.history.canRedo;
|
|
1548
|
-
return
|
|
1445
|
+
return useSyncExternalStore2(subscribe, canRedo, canRedo);
|
|
1549
1446
|
}
|
|
1550
1447
|
function useBatch() {
|
|
1551
1448
|
return useRoom().batch;
|
|
@@ -1594,11 +1491,11 @@ function createRoomContext(client, options) {
|
|
|
1594
1491
|
(rootOrNull2) => rootOrNull2 !== null ? selector(rootOrNull2) : null,
|
|
1595
1492
|
[selector]
|
|
1596
1493
|
);
|
|
1597
|
-
const
|
|
1494
|
+
const subscribe = React3.useCallback(
|
|
1598
1495
|
(onStoreChange) => rootOrNull !== null ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true }) : noop2,
|
|
1599
1496
|
[room, rootOrNull]
|
|
1600
1497
|
);
|
|
1601
|
-
const
|
|
1498
|
+
const getSnapshot = React3.useCallback(() => {
|
|
1602
1499
|
if (rootOrNull === null) {
|
|
1603
1500
|
return null;
|
|
1604
1501
|
} else {
|
|
@@ -1608,9 +1505,9 @@ function createRoomContext(client, options) {
|
|
|
1608
1505
|
}
|
|
1609
1506
|
}, [rootOrNull]);
|
|
1610
1507
|
const getServerSnapshot = alwaysNull;
|
|
1611
|
-
return
|
|
1612
|
-
|
|
1613
|
-
|
|
1508
|
+
return useSyncExternalStoreWithSelector2(
|
|
1509
|
+
subscribe,
|
|
1510
|
+
getSnapshot,
|
|
1614
1511
|
getServerSnapshot,
|
|
1615
1512
|
wrappedSelector,
|
|
1616
1513
|
isEqual
|