@liveblocks/react 1.8.1 → 1.9.0-example1
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 +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +708 -536
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +717 -545
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
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.
|
|
8
|
+
var PKG_VERSION = "1.9.0-example1";
|
|
9
9
|
var PKG_FORMAT = "cjs";
|
|
10
10
|
|
|
11
11
|
// src/ClientSideSuspense.tsx
|
|
@@ -95,18 +95,245 @@ var RemoveReactionError = class extends Error {
|
|
|
95
95
|
}
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
// src/comments/
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
98
|
+
// src/comments/lib/revalidation.ts
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
// src/comments/lib/use-is-document-visible.ts
|
|
103
|
+
|
|
104
|
+
function useIsDocumentVisible() {
|
|
105
|
+
const isVisible = _indexjs.useSyncExternalStore.call(void 0, subscribe, getSnapshot, getSnapshot);
|
|
106
|
+
return isVisible;
|
|
107
|
+
}
|
|
108
|
+
function subscribe(onStoreChange) {
|
|
109
|
+
document.addEventListener("visibilitychange", onStoreChange);
|
|
110
|
+
return () => {
|
|
111
|
+
document.removeEventListener("visibilitychange", onStoreChange);
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function getSnapshot() {
|
|
115
|
+
const isDocumentDefined = typeof document !== "undefined";
|
|
116
|
+
return isDocumentDefined ? document.visibilityState === "visible" : true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/comments/lib/use-is-online.ts
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
function useIsOnline() {
|
|
123
|
+
const isOnlineRef = _react.useRef.call(void 0, true);
|
|
124
|
+
const subscribe2 = _react.useCallback.call(void 0, (onStoreChange) => {
|
|
125
|
+
function handleIsOnline() {
|
|
126
|
+
isOnlineRef.current = true;
|
|
127
|
+
onStoreChange();
|
|
128
|
+
}
|
|
129
|
+
function handleIsOffline() {
|
|
130
|
+
isOnlineRef.current = false;
|
|
131
|
+
onStoreChange();
|
|
132
|
+
}
|
|
133
|
+
window.addEventListener("online", handleIsOnline);
|
|
134
|
+
window.addEventListener("offline", handleIsOffline);
|
|
135
|
+
return () => {
|
|
136
|
+
window.removeEventListener("online", handleIsOnline);
|
|
137
|
+
window.removeEventListener("offline", handleIsOffline);
|
|
138
|
+
};
|
|
139
|
+
}, []);
|
|
140
|
+
const getSnapshot2 = _react.useCallback.call(void 0, () => {
|
|
141
|
+
return isOnlineRef.current;
|
|
142
|
+
}, []);
|
|
143
|
+
const isOnline = _indexjs.useSyncExternalStore.call(void 0, subscribe2, getSnapshot2, getSnapshot2);
|
|
144
|
+
return isOnline;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/comments/lib/revalidation.ts
|
|
148
|
+
var DEFAULT_ERROR_RETRY_INTERVAL = 5e3;
|
|
149
|
+
var DEFAULT_MAX_ERROR_RETRY_COUNT = 5;
|
|
150
|
+
var DEFAULT_DEDUPING_INTERVAL = 2e3;
|
|
151
|
+
var timestamp = 0;
|
|
152
|
+
function useRevalidateCache(manager, fetcher, options = {}) {
|
|
153
|
+
const isOnlineRef = _react.useRef.call(void 0, true);
|
|
154
|
+
const {
|
|
155
|
+
dedupingInterval = DEFAULT_DEDUPING_INTERVAL,
|
|
156
|
+
errorRetryInterval = DEFAULT_ERROR_RETRY_INTERVAL,
|
|
157
|
+
errorRetryCount = DEFAULT_MAX_ERROR_RETRY_COUNT
|
|
158
|
+
} = options;
|
|
159
|
+
const _revalidateCache = _react.useCallback.call(void 0,
|
|
160
|
+
async (shouldDedupe, retryCount = 0) => {
|
|
161
|
+
let startAt;
|
|
162
|
+
const shouldStartRequest = !manager.request || !shouldDedupe;
|
|
163
|
+
function deleteActiveRequest() {
|
|
164
|
+
const activeRequest = manager.request;
|
|
165
|
+
if (!activeRequest)
|
|
166
|
+
return;
|
|
167
|
+
if (activeRequest.timestamp !== startAt)
|
|
168
|
+
return;
|
|
169
|
+
manager.request = void 0;
|
|
170
|
+
}
|
|
171
|
+
function handleError() {
|
|
172
|
+
const timeout = ~~((Math.random() + 0.5) * (1 << (retryCount < 8 ? retryCount : 8))) * errorRetryInterval;
|
|
173
|
+
if (retryCount > errorRetryCount)
|
|
174
|
+
return;
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
void _revalidateCache(false, retryCount + 1);
|
|
177
|
+
}, timeout);
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
if (shouldStartRequest) {
|
|
181
|
+
const currentCache = manager.cache;
|
|
182
|
+
if (!currentCache)
|
|
183
|
+
manager.cache = { isLoading: true };
|
|
184
|
+
manager.request = {
|
|
185
|
+
fetcher: fetcher(),
|
|
186
|
+
timestamp: ++timestamp
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const activeRequest = manager.request;
|
|
190
|
+
if (!activeRequest)
|
|
191
|
+
return;
|
|
192
|
+
startAt = activeRequest.timestamp;
|
|
193
|
+
const newData = await activeRequest.fetcher;
|
|
194
|
+
if (shouldStartRequest) {
|
|
195
|
+
setTimeout(deleteActiveRequest, dedupingInterval);
|
|
196
|
+
}
|
|
197
|
+
if (!manager.request || manager.request.timestamp !== startAt)
|
|
198
|
+
return;
|
|
199
|
+
const activeMutation = manager.mutation;
|
|
200
|
+
if (activeMutation && (activeMutation.startTime > startAt || activeMutation.endTime > startAt || activeMutation.endTime === 0)) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
manager.cache = {
|
|
204
|
+
isLoading: false,
|
|
205
|
+
data: newData
|
|
206
|
+
};
|
|
207
|
+
} catch (err) {
|
|
208
|
+
deleteActiveRequest();
|
|
209
|
+
const isVisible = document.visibilityState === "visible";
|
|
210
|
+
const isOnline = isOnlineRef.current;
|
|
211
|
+
if (shouldStartRequest && isVisible && isOnline)
|
|
212
|
+
handleError();
|
|
213
|
+
manager.cache = {
|
|
214
|
+
data: _optionalChain([manager, 'access', _ => _.cache, 'optionalAccess', _2 => _2.data]),
|
|
215
|
+
isLoading: false,
|
|
216
|
+
error: err
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return;
|
|
220
|
+
},
|
|
221
|
+
[manager, fetcher, dedupingInterval, errorRetryInterval, errorRetryCount]
|
|
222
|
+
);
|
|
223
|
+
_react.useEffect.call(void 0, () => {
|
|
224
|
+
function handleIsOnline() {
|
|
225
|
+
isOnlineRef.current = true;
|
|
226
|
+
}
|
|
227
|
+
function handleIsOffline() {
|
|
228
|
+
isOnlineRef.current = false;
|
|
229
|
+
}
|
|
230
|
+
window.addEventListener("online", handleIsOnline);
|
|
231
|
+
window.addEventListener("offline", handleIsOffline);
|
|
232
|
+
return () => {
|
|
233
|
+
window.removeEventListener("online", handleIsOnline);
|
|
234
|
+
window.removeEventListener("offline", handleIsOffline);
|
|
235
|
+
};
|
|
236
|
+
}, []);
|
|
237
|
+
const revalidateCache = _react.useCallback.call(void 0,
|
|
238
|
+
(shoulDedupe) => {
|
|
239
|
+
return _revalidateCache(shoulDedupe, 0);
|
|
240
|
+
},
|
|
241
|
+
[_revalidateCache]
|
|
242
|
+
);
|
|
243
|
+
return revalidateCache;
|
|
244
|
+
}
|
|
245
|
+
function useMutate(manager, revalidateCache) {
|
|
246
|
+
const mutate = _react.useCallback.call(void 0,
|
|
247
|
+
async (data, options) => {
|
|
248
|
+
const beforeMutationTimestamp = ++timestamp;
|
|
249
|
+
manager.mutation = {
|
|
250
|
+
startTime: beforeMutationTimestamp,
|
|
251
|
+
endTime: 0
|
|
252
|
+
};
|
|
253
|
+
const currentCache = manager.cache;
|
|
254
|
+
manager.cache = {
|
|
255
|
+
isLoading: false,
|
|
256
|
+
data: options.optimisticData
|
|
257
|
+
};
|
|
258
|
+
let error;
|
|
259
|
+
try {
|
|
260
|
+
await data;
|
|
261
|
+
} catch (err) {
|
|
262
|
+
error = err;
|
|
263
|
+
}
|
|
264
|
+
const activeMutation = manager.mutation;
|
|
265
|
+
if (activeMutation && beforeMutationTimestamp !== activeMutation.startTime) {
|
|
266
|
+
if (error)
|
|
267
|
+
throw error;
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (error) {
|
|
271
|
+
manager.cache = currentCache;
|
|
272
|
+
}
|
|
273
|
+
manager.mutation = {
|
|
274
|
+
startTime: beforeMutationTimestamp,
|
|
275
|
+
endTime: ++timestamp
|
|
276
|
+
};
|
|
277
|
+
manager.request = void 0;
|
|
278
|
+
void revalidateCache(false);
|
|
279
|
+
if (error)
|
|
280
|
+
throw error;
|
|
281
|
+
},
|
|
282
|
+
[manager, revalidateCache]
|
|
283
|
+
);
|
|
284
|
+
return mutate;
|
|
285
|
+
}
|
|
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
|
+
_react.useEffect.call(void 0, () => {
|
|
295
|
+
let revalidationTimerId;
|
|
296
|
+
function scheduleRevalidation() {
|
|
297
|
+
if (refreshInterval === 0)
|
|
298
|
+
return;
|
|
299
|
+
revalidationTimerId = window.setTimeout(() => {
|
|
300
|
+
if (isOnline && isDocumentVisible && !_optionalChain([manager, 'access', _3 => _3.cache, 'optionalAccess', _4 => _4.error])) {
|
|
301
|
+
void revalidateCache(true).then(scheduleRevalidation);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
scheduleRevalidation();
|
|
305
|
+
}, refreshInterval);
|
|
306
|
+
}
|
|
307
|
+
scheduleRevalidation();
|
|
308
|
+
return () => {
|
|
309
|
+
window.clearTimeout(revalidationTimerId);
|
|
310
|
+
};
|
|
311
|
+
}, [revalidateCache, refreshInterval, isOnline, isDocumentVisible, manager]);
|
|
312
|
+
_react.useEffect.call(void 0, () => {
|
|
313
|
+
function handleIsOnline() {
|
|
314
|
+
if (revalidateOnReconnect && isDocumentVisible) {
|
|
315
|
+
void revalidateCache(true);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
window.addEventListener("online", handleIsOnline);
|
|
319
|
+
return () => {
|
|
320
|
+
window.removeEventListener("online", handleIsOnline);
|
|
321
|
+
};
|
|
322
|
+
}, [revalidateCache, revalidateOnReconnect, isDocumentVisible]);
|
|
323
|
+
_react.useEffect.call(void 0, () => {
|
|
324
|
+
function handleVisibilityChange() {
|
|
325
|
+
const isVisible = document.visibilityState === "visible";
|
|
326
|
+
if (revalidateOnFocus && isVisible && isOnline) {
|
|
327
|
+
void revalidateCache(true);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
331
|
+
return () => {
|
|
332
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
333
|
+
};
|
|
334
|
+
}, [revalidateCache, revalidateOnFocus, isOnline]);
|
|
108
335
|
}
|
|
109
|
-
function
|
|
336
|
+
function createCacheManager() {
|
|
110
337
|
let cache;
|
|
111
338
|
let request;
|
|
112
339
|
let mutation;
|
|
@@ -136,506 +363,472 @@ function createThreadsManager() {
|
|
|
136
363
|
}
|
|
137
364
|
};
|
|
138
365
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
366
|
+
|
|
367
|
+
// src/comments/CommentsRoom.ts
|
|
368
|
+
var POLLING_INTERVAL_REALTIME = 3e4;
|
|
369
|
+
var POLLING_INTERVAL = 5e3;
|
|
370
|
+
var THREAD_ID_PREFIX = "th";
|
|
371
|
+
var COMMENT_ID_PREFIX = "cm";
|
|
372
|
+
function createOptimisticId(prefix) {
|
|
373
|
+
return `${prefix}_${_nanoid.nanoid.call(void 0, )}`;
|
|
374
|
+
}
|
|
375
|
+
function getPollingInterval(isBrowserOnline, isDocumentVisible, isRoomConnected) {
|
|
376
|
+
if (!isBrowserOnline || !isDocumentVisible)
|
|
377
|
+
return;
|
|
378
|
+
if (isRoomConnected)
|
|
379
|
+
return POLLING_INTERVAL_REALTIME;
|
|
380
|
+
return POLLING_INTERVAL;
|
|
146
381
|
}
|
|
147
382
|
function createCommentsRoom(room, errorEventSource) {
|
|
148
|
-
const manager =
|
|
149
|
-
|
|
150
|
-
let commentsEventRefCount = 0;
|
|
151
|
-
let commentsEventDisposer;
|
|
152
|
-
async function mutate(data, options) {
|
|
153
|
-
const beforeMutationTimestamp = ++timestamp;
|
|
154
|
-
manager.mutation = {
|
|
155
|
-
startTime: beforeMutationTimestamp,
|
|
156
|
-
endTime: 0
|
|
157
|
-
};
|
|
158
|
-
const currentCache = manager.cache;
|
|
159
|
-
manager.cache = {
|
|
160
|
-
isLoading: false,
|
|
161
|
-
threads: options.optimisticData
|
|
162
|
-
};
|
|
163
|
-
try {
|
|
164
|
-
await data;
|
|
165
|
-
const activeMutation = manager.mutation;
|
|
166
|
-
if (activeMutation && beforeMutationTimestamp !== activeMutation.startTime) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
} catch (err) {
|
|
170
|
-
manager.cache = currentCache;
|
|
171
|
-
throw err;
|
|
172
|
-
}
|
|
173
|
-
manager.mutation = {
|
|
174
|
-
startTime: beforeMutationTimestamp,
|
|
175
|
-
endTime: ++timestamp
|
|
176
|
-
};
|
|
177
|
-
manager.request = void 0;
|
|
178
|
-
void revalidateCache(false);
|
|
179
|
-
}
|
|
180
|
-
async function revalidateCache(shouldDedupe, retryCount = 0) {
|
|
181
|
-
let startAt;
|
|
182
|
-
const shouldStartRequest = !manager.request || !shouldDedupe;
|
|
183
|
-
function deleteActiveRequest() {
|
|
184
|
-
const activeRequest = manager.request;
|
|
185
|
-
if (!activeRequest)
|
|
186
|
-
return;
|
|
187
|
-
if (activeRequest.timestamp !== startAt)
|
|
188
|
-
return;
|
|
189
|
-
manager.request = void 0;
|
|
190
|
-
}
|
|
191
|
-
function handleError() {
|
|
192
|
-
const timeout = ~~((Math.random() + 0.5) * (1 << (retryCount < 8 ? retryCount : 8))) * ERROR_RETRY_INTERVAL;
|
|
193
|
-
if (retryCount > MAX_ERROR_RETRY_COUNT)
|
|
194
|
-
return;
|
|
195
|
-
setTimeout(() => {
|
|
196
|
-
void revalidateCache(true, retryCount + 1);
|
|
197
|
-
}, timeout);
|
|
198
|
-
}
|
|
199
|
-
try {
|
|
200
|
-
if (shouldStartRequest) {
|
|
201
|
-
const currentCache = manager.cache;
|
|
202
|
-
if (!currentCache)
|
|
203
|
-
manager.cache = { isLoading: true };
|
|
204
|
-
manager.request = {
|
|
205
|
-
fetcher: room.getThreads(),
|
|
206
|
-
timestamp: ++timestamp
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
const activeRequest = manager.request;
|
|
210
|
-
if (!activeRequest)
|
|
211
|
-
return;
|
|
212
|
-
const newData = await activeRequest.fetcher;
|
|
213
|
-
startAt = activeRequest.timestamp;
|
|
214
|
-
if (shouldStartRequest) {
|
|
215
|
-
setTimeout(deleteActiveRequest, DEDUPING_INTERVAL);
|
|
216
|
-
}
|
|
217
|
-
if (!manager.request || manager.request.timestamp !== startAt)
|
|
218
|
-
return;
|
|
219
|
-
const activeMutation = manager.mutation;
|
|
220
|
-
if (activeMutation && (activeMutation.startTime > startAt || activeMutation.endTime > startAt || activeMutation.endTime === 0)) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
manager.cache = {
|
|
224
|
-
isLoading: false,
|
|
225
|
-
threads: newData
|
|
226
|
-
};
|
|
227
|
-
} catch (err) {
|
|
228
|
-
if (shouldStartRequest)
|
|
229
|
-
handleError();
|
|
230
|
-
deleteActiveRequest();
|
|
231
|
-
manager.cache = {
|
|
232
|
-
isLoading: false,
|
|
233
|
-
error: err
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
function editThreadMetadata(options) {
|
|
238
|
-
const threadId = options.threadId;
|
|
239
|
-
const metadata = "metadata" in options ? options.metadata : {};
|
|
240
|
-
const threads = getThreads();
|
|
241
|
-
const optimisticData = threads.map(
|
|
242
|
-
(thread) => thread.id === threadId ? {
|
|
243
|
-
...thread,
|
|
244
|
-
metadata: {
|
|
245
|
-
...thread.metadata,
|
|
246
|
-
...metadata
|
|
247
|
-
}
|
|
248
|
-
} : thread
|
|
249
|
-
);
|
|
250
|
-
mutate(room.editThreadMetadata({ metadata, threadId }), {
|
|
251
|
-
optimisticData
|
|
252
|
-
}).catch((err) => {
|
|
253
|
-
if (!(err instanceof _core.CommentsApiError)) {
|
|
254
|
-
throw err;
|
|
255
|
-
}
|
|
256
|
-
const error = handleCommentsApiError(err);
|
|
257
|
-
errorEventSource.notify(
|
|
258
|
-
new EditThreadMetadataError(error, {
|
|
259
|
-
roomId: room.id,
|
|
260
|
-
threadId,
|
|
261
|
-
metadata
|
|
262
|
-
})
|
|
263
|
-
);
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
function createThread(options) {
|
|
267
|
-
const body = options.body;
|
|
268
|
-
const metadata = "metadata" in options ? options.metadata : {};
|
|
269
|
-
const threads = getThreads();
|
|
270
|
-
const threadId = createOptimisticId(THREAD_ID_PREFIX);
|
|
271
|
-
const commentId = createOptimisticId(COMMENT_ID_PREFIX);
|
|
272
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
273
|
-
const newComment = {
|
|
274
|
-
id: commentId,
|
|
275
|
-
threadId,
|
|
276
|
-
roomId: room.id,
|
|
277
|
-
createdAt: now,
|
|
278
|
-
type: "comment",
|
|
279
|
-
userId: getCurrentUserId(),
|
|
280
|
-
body,
|
|
281
|
-
reactions: []
|
|
282
|
-
};
|
|
283
|
-
const newThread = {
|
|
284
|
-
id: threadId,
|
|
285
|
-
type: "thread",
|
|
286
|
-
createdAt: now,
|
|
287
|
-
roomId: room.id,
|
|
288
|
-
metadata,
|
|
289
|
-
comments: [newComment]
|
|
290
|
-
};
|
|
291
|
-
mutate(room.createThread({ threadId, commentId, body, metadata }), {
|
|
292
|
-
optimisticData: [...threads, newThread]
|
|
293
|
-
}).catch((err) => {
|
|
294
|
-
if (!(err instanceof _core.CommentsApiError)) {
|
|
295
|
-
throw err;
|
|
296
|
-
}
|
|
297
|
-
const error = handleCommentsApiError(err);
|
|
298
|
-
errorEventSource.notify(
|
|
299
|
-
new CreateThreadError(error, {
|
|
300
|
-
roomId: room.id,
|
|
301
|
-
threadId,
|
|
302
|
-
commentId,
|
|
303
|
-
body,
|
|
304
|
-
metadata
|
|
305
|
-
})
|
|
306
|
-
);
|
|
307
|
-
});
|
|
308
|
-
return newThread;
|
|
309
|
-
}
|
|
310
|
-
function createComment({
|
|
311
|
-
threadId,
|
|
312
|
-
body
|
|
313
|
-
}) {
|
|
314
|
-
const threads = getThreads();
|
|
315
|
-
const commentId = createOptimisticId(COMMENT_ID_PREFIX);
|
|
316
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
317
|
-
const comment = {
|
|
318
|
-
id: commentId,
|
|
319
|
-
threadId,
|
|
320
|
-
roomId: room.id,
|
|
321
|
-
type: "comment",
|
|
322
|
-
createdAt: now,
|
|
323
|
-
userId: getCurrentUserId(),
|
|
324
|
-
body,
|
|
325
|
-
reactions: []
|
|
326
|
-
};
|
|
327
|
-
const optimisticData = threads.map(
|
|
328
|
-
(thread) => thread.id === threadId ? {
|
|
329
|
-
...thread,
|
|
330
|
-
comments: [...thread.comments, comment]
|
|
331
|
-
} : thread
|
|
332
|
-
);
|
|
333
|
-
mutate(room.createComment({ threadId, commentId, body }), {
|
|
334
|
-
optimisticData
|
|
335
|
-
}).catch((err) => {
|
|
336
|
-
if (!(err instanceof _core.CommentsApiError)) {
|
|
337
|
-
throw err;
|
|
338
|
-
}
|
|
339
|
-
const error = handleCommentsApiError(err);
|
|
340
|
-
errorEventSource.notify(
|
|
341
|
-
new CreateCommentError(error, {
|
|
342
|
-
roomId: room.id,
|
|
343
|
-
threadId,
|
|
344
|
-
commentId,
|
|
345
|
-
body
|
|
346
|
-
})
|
|
347
|
-
);
|
|
348
|
-
});
|
|
349
|
-
return comment;
|
|
350
|
-
}
|
|
351
|
-
function editComment({ threadId, commentId, body }) {
|
|
352
|
-
const threads = getThreads();
|
|
353
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
354
|
-
const optimisticData = threads.map(
|
|
355
|
-
(thread) => thread.id === threadId ? {
|
|
356
|
-
...thread,
|
|
357
|
-
comments: thread.comments.map(
|
|
358
|
-
(comment) => comment.id === commentId ? {
|
|
359
|
-
...comment,
|
|
360
|
-
editedAt: now,
|
|
361
|
-
body
|
|
362
|
-
} : comment
|
|
363
|
-
)
|
|
364
|
-
} : thread
|
|
365
|
-
);
|
|
366
|
-
mutate(room.editComment({ threadId, commentId, body }), {
|
|
367
|
-
optimisticData
|
|
368
|
-
}).catch((err) => {
|
|
369
|
-
if (!(err instanceof _core.CommentsApiError)) {
|
|
370
|
-
throw err;
|
|
371
|
-
}
|
|
372
|
-
const error = handleCommentsApiError(err);
|
|
373
|
-
errorEventSource.notify(
|
|
374
|
-
new EditCommentError(error, {
|
|
375
|
-
roomId: room.id,
|
|
376
|
-
threadId,
|
|
377
|
-
commentId,
|
|
378
|
-
body
|
|
379
|
-
})
|
|
380
|
-
);
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
function deleteComment({ threadId, commentId }) {
|
|
384
|
-
const threads = getThreads();
|
|
385
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
386
|
-
const newThreads = [];
|
|
387
|
-
for (const thread of threads) {
|
|
388
|
-
if (thread.id === threadId) {
|
|
389
|
-
const newThread = {
|
|
390
|
-
...thread,
|
|
391
|
-
comments: thread.comments.map(
|
|
392
|
-
(comment) => comment.id === commentId ? {
|
|
393
|
-
...comment,
|
|
394
|
-
deletedAt: now,
|
|
395
|
-
body: void 0
|
|
396
|
-
} : comment
|
|
397
|
-
)
|
|
398
|
-
};
|
|
399
|
-
if (newThread.comments.some((comment) => comment.deletedAt === void 0)) {
|
|
400
|
-
newThreads.push(newThread);
|
|
401
|
-
}
|
|
402
|
-
} else {
|
|
403
|
-
newThreads.push(thread);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
mutate(room.deleteComment({ threadId, commentId }), {
|
|
407
|
-
optimisticData: newThreads
|
|
408
|
-
}).catch((err) => {
|
|
409
|
-
if (!(err instanceof _core.CommentsApiError)) {
|
|
410
|
-
throw err;
|
|
411
|
-
}
|
|
412
|
-
const error = handleCommentsApiError(err);
|
|
413
|
-
errorEventSource.notify(
|
|
414
|
-
new DeleteCommentError(error, {
|
|
415
|
-
roomId: room.id,
|
|
416
|
-
threadId,
|
|
417
|
-
commentId
|
|
418
|
-
})
|
|
419
|
-
);
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
function getCurrentUserId() {
|
|
423
|
-
const self = room.getSelf();
|
|
424
|
-
if (self === null || self.id === void 0) {
|
|
425
|
-
return "anonymous";
|
|
426
|
-
} else {
|
|
427
|
-
return self.id;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
function getThreads() {
|
|
431
|
-
const threads = manager.cache;
|
|
432
|
-
if (!threads || threads.isLoading || threads.error) {
|
|
433
|
-
throw new Error(
|
|
434
|
-
"Cannot update threads or comments before they are loaded."
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
return threads.threads;
|
|
438
|
-
}
|
|
439
|
-
function _subscribe() {
|
|
440
|
-
if (commentsEventRefCount === 0) {
|
|
441
|
-
commentsEventDisposer = room.events.comments.subscribe(() => {
|
|
442
|
-
void revalidateCache(true);
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
commentsEventRefCount = commentsEventRefCount + 1;
|
|
446
|
-
return () => {
|
|
447
|
-
commentsEventRefCount = commentsEventRefCount - 1;
|
|
448
|
-
if (commentsEventRefCount > 0)
|
|
449
|
-
return;
|
|
450
|
-
_optionalChain([commentsEventDisposer, 'optionalCall', _3 => _3()]);
|
|
451
|
-
commentsEventDisposer = void 0;
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
function usePolling() {
|
|
383
|
+
const manager = createCacheManager();
|
|
384
|
+
function _useThreads(revalidateCache) {
|
|
455
385
|
const status = _indexjs.useSyncExternalStore.call(void 0,
|
|
456
386
|
room.events.status.subscribe,
|
|
457
387
|
room.getStatus,
|
|
458
388
|
room.getStatus
|
|
459
389
|
);
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
executeRevalidation,
|
|
467
|
-
interval
|
|
468
|
-
);
|
|
469
|
-
}
|
|
470
|
-
function executeRevalidation() {
|
|
471
|
-
void revalidateCache(true).then(scheduleRevalidation);
|
|
472
|
-
}
|
|
473
|
-
scheduleRevalidation();
|
|
474
|
-
return () => {
|
|
475
|
-
window.clearTimeout(revalidationTimerId);
|
|
476
|
-
};
|
|
477
|
-
},
|
|
478
|
-
// 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`
|
|
479
|
-
[status, revalidateCache]
|
|
390
|
+
const isOnline = useIsOnline();
|
|
391
|
+
const isDocumentVisible = useIsDocumentVisible();
|
|
392
|
+
const interval = getPollingInterval(
|
|
393
|
+
isOnline,
|
|
394
|
+
isDocumentVisible,
|
|
395
|
+
status === "connected"
|
|
480
396
|
);
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
397
|
+
useAutomaticRevalidation(manager, revalidateCache, {
|
|
398
|
+
revalidateOnFocus: true,
|
|
399
|
+
revalidateOnReconnect: true,
|
|
400
|
+
refreshInterval: interval
|
|
401
|
+
});
|
|
402
|
+
_react.useEffect.call(void 0, () => {
|
|
403
|
+
const unsubscribe = room.events.comments.subscribe(() => {
|
|
404
|
+
void revalidateCache(true);
|
|
405
|
+
});
|
|
406
|
+
return () => {
|
|
407
|
+
unsubscribe();
|
|
408
|
+
};
|
|
409
|
+
}, [revalidateCache]);
|
|
485
410
|
const cache = _indexjs.useSyncExternalStore.call(void 0,
|
|
486
411
|
manager.subscribe,
|
|
487
412
|
() => manager.cache,
|
|
488
413
|
() => manager.cache
|
|
489
414
|
);
|
|
490
|
-
|
|
415
|
+
if (!cache || cache.isLoading) {
|
|
416
|
+
return { isLoading: true };
|
|
417
|
+
}
|
|
418
|
+
return {
|
|
419
|
+
isLoading: cache.isLoading,
|
|
420
|
+
threads: _nullishCoalesce(cache.data, () => ( [])),
|
|
421
|
+
error: cache.error
|
|
422
|
+
};
|
|
491
423
|
}
|
|
492
424
|
function useThreads() {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
[revalidateCache]
|
|
499
|
-
);
|
|
500
|
-
return useThreadsInternal();
|
|
425
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
426
|
+
_react.useEffect.call(void 0, () => {
|
|
427
|
+
void revalidate(true);
|
|
428
|
+
}, [revalidate]);
|
|
429
|
+
return _useThreads(revalidate);
|
|
501
430
|
}
|
|
502
431
|
function useThreadsSuspense() {
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
throw revalidateCache(true);
|
|
506
|
-
}
|
|
432
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
433
|
+
const cache = _useThreads(revalidate);
|
|
507
434
|
if (cache.error) {
|
|
508
435
|
throw cache.error;
|
|
509
436
|
}
|
|
437
|
+
if (cache.isLoading || !cache.threads) {
|
|
438
|
+
throw revalidate(true);
|
|
439
|
+
}
|
|
510
440
|
return {
|
|
511
441
|
threads: cache.threads,
|
|
512
442
|
isLoading: false
|
|
513
443
|
};
|
|
514
444
|
}
|
|
515
|
-
function
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
);
|
|
538
|
-
} else {
|
|
539
|
-
reactions = [
|
|
540
|
-
...comment.reactions,
|
|
541
|
-
{
|
|
542
|
-
emoji,
|
|
543
|
-
createdAt: now,
|
|
544
|
-
users: [{ id: userId }]
|
|
545
|
-
}
|
|
546
|
-
];
|
|
445
|
+
function useEditThreadMetadata() {
|
|
446
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
447
|
+
const mutate = useMutate(manager, revalidate);
|
|
448
|
+
const editThreadMetadata = _react.useCallback.call(void 0,
|
|
449
|
+
(options) => {
|
|
450
|
+
const threadId = options.threadId;
|
|
451
|
+
const metadata = "metadata" in options ? options.metadata : {};
|
|
452
|
+
const threads = getThreads();
|
|
453
|
+
const optimisticData = threads.map(
|
|
454
|
+
(thread) => thread.id === threadId ? {
|
|
455
|
+
...thread,
|
|
456
|
+
metadata: {
|
|
457
|
+
...thread.metadata,
|
|
458
|
+
...metadata
|
|
459
|
+
}
|
|
460
|
+
} : thread
|
|
461
|
+
);
|
|
462
|
+
mutate(room.editThreadMetadata({ metadata, threadId }), {
|
|
463
|
+
optimisticData
|
|
464
|
+
}).catch((err) => {
|
|
465
|
+
if (!(err instanceof _core.CommentsApiError)) {
|
|
466
|
+
throw err;
|
|
547
467
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
468
|
+
const error = handleCommentsApiError(err);
|
|
469
|
+
errorEventSource.notify(
|
|
470
|
+
new EditThreadMetadataError(error, {
|
|
471
|
+
roomId: room.id,
|
|
472
|
+
threadId,
|
|
473
|
+
metadata
|
|
474
|
+
})
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
},
|
|
478
|
+
[mutate]
|
|
554
479
|
);
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
480
|
+
return editThreadMetadata;
|
|
481
|
+
}
|
|
482
|
+
function useCreateThread() {
|
|
483
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
484
|
+
const mutate = useMutate(manager, revalidate);
|
|
485
|
+
const createThread = _react.useCallback.call(void 0,
|
|
486
|
+
(options) => {
|
|
487
|
+
const body = options.body;
|
|
488
|
+
const metadata = "metadata" in options ? options.metadata : {};
|
|
489
|
+
const threads = getThreads();
|
|
490
|
+
const threadId = createOptimisticId(THREAD_ID_PREFIX);
|
|
491
|
+
const commentId = createOptimisticId(COMMENT_ID_PREFIX);
|
|
492
|
+
const now = /* @__PURE__ */ new Date();
|
|
493
|
+
const newComment = {
|
|
494
|
+
id: commentId,
|
|
495
|
+
threadId,
|
|
564
496
|
roomId: room.id,
|
|
497
|
+
createdAt: now,
|
|
498
|
+
type: "comment",
|
|
499
|
+
userId: getCurrentUserId(),
|
|
500
|
+
body,
|
|
501
|
+
reactions: []
|
|
502
|
+
};
|
|
503
|
+
const newThread = {
|
|
504
|
+
id: threadId,
|
|
505
|
+
type: "thread",
|
|
506
|
+
createdAt: now,
|
|
507
|
+
roomId: room.id,
|
|
508
|
+
metadata,
|
|
509
|
+
comments: [newComment]
|
|
510
|
+
};
|
|
511
|
+
mutate(room.createThread({ threadId, commentId, body, metadata }), {
|
|
512
|
+
optimisticData: [...threads, newThread]
|
|
513
|
+
}).catch((err) => {
|
|
514
|
+
if (!(err instanceof _core.CommentsApiError)) {
|
|
515
|
+
throw err;
|
|
516
|
+
}
|
|
517
|
+
const error = handleCommentsApiError(err);
|
|
518
|
+
errorEventSource.notify(
|
|
519
|
+
new CreateThreadError(error, {
|
|
520
|
+
roomId: room.id,
|
|
521
|
+
threadId,
|
|
522
|
+
commentId,
|
|
523
|
+
body,
|
|
524
|
+
metadata
|
|
525
|
+
})
|
|
526
|
+
);
|
|
527
|
+
});
|
|
528
|
+
return newThread;
|
|
529
|
+
},
|
|
530
|
+
[mutate]
|
|
531
|
+
);
|
|
532
|
+
return createThread;
|
|
533
|
+
}
|
|
534
|
+
function useCreateComment() {
|
|
535
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
536
|
+
const mutate = useMutate(manager, revalidate);
|
|
537
|
+
const createComment = _react.useCallback.call(void 0,
|
|
538
|
+
({ threadId, body }) => {
|
|
539
|
+
const threads = getThreads();
|
|
540
|
+
const commentId = createOptimisticId(COMMENT_ID_PREFIX);
|
|
541
|
+
const now = /* @__PURE__ */ new Date();
|
|
542
|
+
const comment = {
|
|
543
|
+
id: commentId,
|
|
565
544
|
threadId,
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
545
|
+
roomId: room.id,
|
|
546
|
+
type: "comment",
|
|
547
|
+
createdAt: now,
|
|
548
|
+
userId: getCurrentUserId(),
|
|
549
|
+
body,
|
|
550
|
+
reactions: []
|
|
551
|
+
};
|
|
552
|
+
const optimisticData = threads.map(
|
|
553
|
+
(thread) => thread.id === threadId ? {
|
|
554
|
+
...thread,
|
|
555
|
+
comments: [...thread.comments, comment]
|
|
556
|
+
} : thread
|
|
557
|
+
);
|
|
558
|
+
mutate(room.createComment({ threadId, commentId, body }), {
|
|
559
|
+
optimisticData
|
|
560
|
+
}).catch((err) => {
|
|
561
|
+
if (!(err instanceof _core.CommentsApiError)) {
|
|
562
|
+
throw err;
|
|
563
|
+
}
|
|
564
|
+
const error = handleCommentsApiError(err);
|
|
565
|
+
errorEventSource.notify(
|
|
566
|
+
new CreateCommentError(error, {
|
|
567
|
+
roomId: room.id,
|
|
568
|
+
threadId,
|
|
569
|
+
commentId,
|
|
570
|
+
body
|
|
571
|
+
})
|
|
572
|
+
);
|
|
573
|
+
});
|
|
574
|
+
return comment;
|
|
575
|
+
},
|
|
576
|
+
[mutate]
|
|
577
|
+
);
|
|
578
|
+
return createComment;
|
|
571
579
|
}
|
|
572
|
-
function
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
580
|
+
function useEditComment() {
|
|
581
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
582
|
+
const mutate = useMutate(manager, revalidate);
|
|
583
|
+
const editComment = _react.useCallback.call(void 0,
|
|
584
|
+
({ threadId, commentId, body }) => {
|
|
585
|
+
const threads = getThreads();
|
|
586
|
+
const now = /* @__PURE__ */ new Date();
|
|
587
|
+
const optimisticData = threads.map(
|
|
588
|
+
(thread) => thread.id === threadId ? {
|
|
589
|
+
...thread,
|
|
590
|
+
comments: thread.comments.map(
|
|
591
|
+
(comment) => comment.id === commentId ? {
|
|
592
|
+
...comment,
|
|
593
|
+
editedAt: now,
|
|
594
|
+
body
|
|
595
|
+
} : comment
|
|
596
|
+
)
|
|
597
|
+
} : thread
|
|
598
|
+
);
|
|
599
|
+
mutate(room.editComment({ threadId, commentId, body }), {
|
|
600
|
+
optimisticData
|
|
601
|
+
}).catch((err) => {
|
|
602
|
+
if (!(err instanceof _core.CommentsApiError)) {
|
|
603
|
+
throw err;
|
|
585
604
|
}
|
|
586
|
-
const
|
|
587
|
-
|
|
605
|
+
const error = handleCommentsApiError(err);
|
|
606
|
+
errorEventSource.notify(
|
|
607
|
+
new EditCommentError(error, {
|
|
608
|
+
roomId: room.id,
|
|
609
|
+
threadId,
|
|
610
|
+
commentId,
|
|
611
|
+
body
|
|
612
|
+
})
|
|
588
613
|
);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
614
|
+
});
|
|
615
|
+
},
|
|
616
|
+
[mutate]
|
|
617
|
+
);
|
|
618
|
+
return editComment;
|
|
619
|
+
}
|
|
620
|
+
function useDeleteComment() {
|
|
621
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
622
|
+
const mutate = useMutate(manager, revalidate);
|
|
623
|
+
const deleteComment = _react.useCallback.call(void 0,
|
|
624
|
+
({ threadId, commentId }) => {
|
|
625
|
+
const threads = getThreads();
|
|
626
|
+
const now = /* @__PURE__ */ new Date();
|
|
627
|
+
const newThreads = [];
|
|
628
|
+
for (const thread of threads) {
|
|
629
|
+
if (thread.id === threadId) {
|
|
630
|
+
const newThread = {
|
|
631
|
+
...thread,
|
|
632
|
+
comments: thread.comments.map(
|
|
633
|
+
(comment) => comment.id === commentId ? {
|
|
634
|
+
...comment,
|
|
635
|
+
deletedAt: now,
|
|
636
|
+
body: void 0
|
|
637
|
+
} : comment
|
|
638
|
+
)
|
|
639
|
+
};
|
|
640
|
+
if (newThread.comments.some(
|
|
641
|
+
(comment) => comment.deletedAt === void 0
|
|
642
|
+
)) {
|
|
643
|
+
newThreads.push(newThread);
|
|
603
644
|
}
|
|
645
|
+
} else {
|
|
646
|
+
newThreads.push(thread);
|
|
604
647
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
648
|
+
}
|
|
649
|
+
mutate(room.deleteComment({ threadId, commentId }), {
|
|
650
|
+
optimisticData: newThreads
|
|
651
|
+
}).catch((err) => {
|
|
652
|
+
if (!(err instanceof _core.CommentsApiError)) {
|
|
653
|
+
throw err;
|
|
654
|
+
}
|
|
655
|
+
const error = handleCommentsApiError(err);
|
|
656
|
+
errorEventSource.notify(
|
|
657
|
+
new DeleteCommentError(error, {
|
|
658
|
+
roomId: room.id,
|
|
659
|
+
threadId,
|
|
660
|
+
commentId
|
|
661
|
+
})
|
|
662
|
+
);
|
|
663
|
+
});
|
|
664
|
+
},
|
|
665
|
+
[mutate]
|
|
611
666
|
);
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
new
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
667
|
+
return deleteComment;
|
|
668
|
+
}
|
|
669
|
+
function useAddReaction() {
|
|
670
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
671
|
+
const mutate = useMutate(manager, revalidate);
|
|
672
|
+
const createComment = _react.useCallback.call(void 0,
|
|
673
|
+
({ threadId, commentId, emoji }) => {
|
|
674
|
+
const threads = getThreads();
|
|
675
|
+
const now = /* @__PURE__ */ new Date();
|
|
676
|
+
const userId = getCurrentUserId();
|
|
677
|
+
const optimisticData = threads.map(
|
|
678
|
+
(thread) => thread.id === threadId ? {
|
|
679
|
+
...thread,
|
|
680
|
+
comments: thread.comments.map((comment) => {
|
|
681
|
+
if (comment.id !== commentId) {
|
|
682
|
+
return comment;
|
|
683
|
+
}
|
|
684
|
+
let reactions;
|
|
685
|
+
if (comment.reactions.some(
|
|
686
|
+
(reaction) => reaction.emoji === emoji
|
|
687
|
+
)) {
|
|
688
|
+
reactions = comment.reactions.map(
|
|
689
|
+
(reaction) => reaction.emoji === emoji ? {
|
|
690
|
+
...reaction,
|
|
691
|
+
users: [...reaction.users, { id: userId }]
|
|
692
|
+
} : reaction
|
|
693
|
+
);
|
|
694
|
+
} else {
|
|
695
|
+
reactions = [
|
|
696
|
+
...comment.reactions,
|
|
697
|
+
{
|
|
698
|
+
emoji,
|
|
699
|
+
createdAt: now,
|
|
700
|
+
users: [{ id: userId }]
|
|
701
|
+
}
|
|
702
|
+
];
|
|
703
|
+
}
|
|
704
|
+
return {
|
|
705
|
+
...comment,
|
|
706
|
+
reactions
|
|
707
|
+
};
|
|
708
|
+
})
|
|
709
|
+
} : thread
|
|
710
|
+
);
|
|
711
|
+
mutate(room.addReaction({ threadId, commentId, emoji }), {
|
|
712
|
+
optimisticData
|
|
713
|
+
}).catch((err) => {
|
|
714
|
+
if (!(err instanceof _core.CommentsApiError)) {
|
|
715
|
+
throw err;
|
|
716
|
+
}
|
|
717
|
+
const error = handleCommentsApiError(err);
|
|
718
|
+
errorEventSource.notify(
|
|
719
|
+
new AddReactionError(error, {
|
|
720
|
+
roomId: room.id,
|
|
721
|
+
threadId,
|
|
722
|
+
commentId,
|
|
723
|
+
emoji
|
|
724
|
+
})
|
|
725
|
+
);
|
|
726
|
+
});
|
|
727
|
+
},
|
|
728
|
+
[mutate]
|
|
729
|
+
);
|
|
730
|
+
return createComment;
|
|
731
|
+
}
|
|
732
|
+
function useRemoveReaction() {
|
|
733
|
+
const revalidate = useRevalidateCache(manager, room.getThreads);
|
|
734
|
+
const mutate = useMutate(manager, revalidate);
|
|
735
|
+
const createComment = _react.useCallback.call(void 0,
|
|
736
|
+
({ threadId, commentId, emoji }) => {
|
|
737
|
+
const threads = getThreads();
|
|
738
|
+
const userId = getCurrentUserId();
|
|
739
|
+
const optimisticData = threads.map(
|
|
740
|
+
(thread) => thread.id === threadId ? {
|
|
741
|
+
...thread,
|
|
742
|
+
comments: thread.comments.map((comment) => {
|
|
743
|
+
if (comment.id !== commentId) {
|
|
744
|
+
return comment;
|
|
745
|
+
}
|
|
746
|
+
const reactionIndex = comment.reactions.findIndex(
|
|
747
|
+
(reaction) => reaction.emoji === emoji
|
|
748
|
+
);
|
|
749
|
+
let reactions = comment.reactions;
|
|
750
|
+
if (reactionIndex >= 0 && comment.reactions[reactionIndex].users.some(
|
|
751
|
+
(user) => user.id === userId
|
|
752
|
+
)) {
|
|
753
|
+
if (comment.reactions[reactionIndex].users.length <= 1) {
|
|
754
|
+
reactions = [...comment.reactions];
|
|
755
|
+
reactions.splice(reactionIndex, 1);
|
|
756
|
+
} else {
|
|
757
|
+
reactions[reactionIndex] = {
|
|
758
|
+
...reactions[reactionIndex],
|
|
759
|
+
users: reactions[reactionIndex].users.filter(
|
|
760
|
+
(user) => user.id !== userId
|
|
761
|
+
)
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return {
|
|
766
|
+
...comment,
|
|
767
|
+
reactions
|
|
768
|
+
};
|
|
769
|
+
})
|
|
770
|
+
} : thread
|
|
771
|
+
);
|
|
772
|
+
mutate(room.removeReaction({ threadId, commentId, emoji }), {
|
|
773
|
+
optimisticData
|
|
774
|
+
}).catch((err) => {
|
|
775
|
+
if (!(err instanceof _core.CommentsApiError)) {
|
|
776
|
+
throw err;
|
|
777
|
+
}
|
|
778
|
+
const error = handleCommentsApiError(err);
|
|
779
|
+
errorEventSource.notify(
|
|
780
|
+
new RemoveReactionError(error, {
|
|
781
|
+
roomId: room.id,
|
|
782
|
+
threadId,
|
|
783
|
+
commentId,
|
|
784
|
+
emoji
|
|
785
|
+
})
|
|
786
|
+
);
|
|
787
|
+
});
|
|
788
|
+
},
|
|
789
|
+
[mutate]
|
|
790
|
+
);
|
|
791
|
+
return createComment;
|
|
792
|
+
}
|
|
793
|
+
function getThreads() {
|
|
794
|
+
const threads = manager.cache;
|
|
795
|
+
if (!threads || threads.isLoading || threads.error || threads.data === void 0) {
|
|
796
|
+
throw new Error(
|
|
797
|
+
"Cannot update threads or comments before they are loaded."
|
|
626
798
|
);
|
|
627
|
-
}
|
|
799
|
+
}
|
|
800
|
+
return threads.data;
|
|
801
|
+
}
|
|
802
|
+
function getCurrentUserId() {
|
|
803
|
+
const self = room.getSelf();
|
|
804
|
+
if (self === null || self.id === void 0) {
|
|
805
|
+
return "anonymous";
|
|
806
|
+
} else {
|
|
807
|
+
return self.id;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
function handleCommentsApiError(err) {
|
|
811
|
+
const message = `Request failed with status ${err.status}: ${err.message}`;
|
|
812
|
+
if (_optionalChain([err, 'access', _5 => _5.details, 'optionalAccess', _6 => _6.error]) === "FORBIDDEN") {
|
|
813
|
+
const detailedMessage = [
|
|
814
|
+
message,
|
|
815
|
+
err.details.suggestion,
|
|
816
|
+
err.details.docs
|
|
817
|
+
].filter(Boolean).join("\n");
|
|
818
|
+
_core.console.error(detailedMessage);
|
|
819
|
+
}
|
|
820
|
+
return new Error(message);
|
|
628
821
|
}
|
|
629
822
|
return {
|
|
630
823
|
useThreads,
|
|
631
824
|
useThreadsSuspense,
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
825
|
+
useCreateThread,
|
|
826
|
+
useEditThreadMetadata,
|
|
827
|
+
useCreateComment,
|
|
828
|
+
useEditComment,
|
|
829
|
+
useDeleteComment,
|
|
830
|
+
useAddReaction,
|
|
831
|
+
useRemoveReaction
|
|
639
832
|
};
|
|
640
833
|
}
|
|
641
834
|
|
|
@@ -691,16 +884,16 @@ function useAsyncCache(cache, key, options) {
|
|
|
691
884
|
void cacheItem2.get();
|
|
692
885
|
return cacheItem2;
|
|
693
886
|
}, [cache, key]);
|
|
694
|
-
const
|
|
695
|
-
(callback) => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess',
|
|
887
|
+
const subscribe2 = _react.useCallback.call(void 0,
|
|
888
|
+
(callback) => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess', _7 => _7.subscribe, 'call', _8 => _8(callback)]), () => ( noop)),
|
|
696
889
|
[cacheItem]
|
|
697
890
|
);
|
|
698
891
|
const getState = _react.useCallback.call(void 0,
|
|
699
|
-
() => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess',
|
|
892
|
+
() => _nullishCoalesce(_optionalChain([cacheItem, 'optionalAccess', _9 => _9.getState, 'call', _10 => _10()]), () => ( INITIAL_ASYNC_STATE)),
|
|
700
893
|
[cacheItem]
|
|
701
894
|
);
|
|
702
|
-
const revalidate = _react.useCallback.call(void 0, () => _optionalChain([cacheItem, 'optionalAccess',
|
|
703
|
-
const state = _indexjs.useSyncExternalStore.call(void 0,
|
|
895
|
+
const revalidate = _react.useCallback.call(void 0, () => _optionalChain([cacheItem, 'optionalAccess', _11 => _11.revalidate, 'call', _12 => _12()]), [cacheItem]);
|
|
896
|
+
const state = _indexjs.useSyncExternalStore.call(void 0, subscribe2, getState, getState);
|
|
704
897
|
const previousData = _react.useRef.call(void 0, );
|
|
705
898
|
let data = state.data;
|
|
706
899
|
_react.useEffect.call(void 0, () => {
|
|
@@ -715,7 +908,7 @@ function useAsyncCache(cache, key, options) {
|
|
|
715
908
|
revalidate
|
|
716
909
|
};
|
|
717
910
|
}
|
|
718
|
-
if (_optionalChain([frozenOptions, 'optionalAccess',
|
|
911
|
+
if (_optionalChain([frozenOptions, 'optionalAccess', _13 => _13.suspense])) {
|
|
719
912
|
const error = getState().error;
|
|
720
913
|
if (error) {
|
|
721
914
|
throw error;
|
|
@@ -729,7 +922,7 @@ function useAsyncCache(cache, key, options) {
|
|
|
729
922
|
});
|
|
730
923
|
}
|
|
731
924
|
}
|
|
732
|
-
if (state.isLoading && _optionalChain([frozenOptions, 'optionalAccess',
|
|
925
|
+
if (state.isLoading && _optionalChain([frozenOptions, 'optionalAccess', _14 => _14.keepPreviousDataWhileLoading]) && typeof state.data === "undefined" && _optionalChain([previousData, 'access', _15 => _15.current, 'optionalAccess', _16 => _16.key]) !== key && typeof _optionalChain([previousData, 'access', _17 => _17.current, 'optionalAccess', _18 => _18.data]) !== "undefined") {
|
|
733
926
|
data = previousData.current.data;
|
|
734
927
|
}
|
|
735
928
|
return {
|
|
@@ -780,7 +973,7 @@ var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\
|
|
|
780
973
|
|
|
781
974
|
Why? Please see https://liveblocks.io/docs/platform/troubleshooting#stale-props-zombie-child for more information`;
|
|
782
975
|
var superfluous_unstable_batchedUpdates = "You don\u2019t need to pass unstable_batchedUpdates to RoomProvider anymore, since you\u2019re on React 18+ already.";
|
|
783
|
-
function
|
|
976
|
+
function useSyncExternalStore5(s, gs, gss) {
|
|
784
977
|
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0, s, gs, gss, identity);
|
|
785
978
|
}
|
|
786
979
|
var STABLE_EMPTY_LIST = Object.freeze([]);
|
|
@@ -931,16 +1124,16 @@ function createRoomContext(client, options) {
|
|
|
931
1124
|
}
|
|
932
1125
|
function useStatus() {
|
|
933
1126
|
const room = useRoom();
|
|
934
|
-
const
|
|
935
|
-
const
|
|
1127
|
+
const subscribe2 = room.events.status.subscribe;
|
|
1128
|
+
const getSnapshot2 = room.getStatus;
|
|
936
1129
|
const getServerSnapshot = room.getStatus;
|
|
937
|
-
return
|
|
1130
|
+
return useSyncExternalStore5(subscribe2, getSnapshot2, getServerSnapshot);
|
|
938
1131
|
}
|
|
939
1132
|
function useMyPresence() {
|
|
940
1133
|
const room = useRoom();
|
|
941
|
-
const
|
|
942
|
-
const
|
|
943
|
-
const presence =
|
|
1134
|
+
const subscribe2 = room.events.myPresence.subscribe;
|
|
1135
|
+
const getSnapshot2 = room.getPresence;
|
|
1136
|
+
const presence = useSyncExternalStore5(subscribe2, getSnapshot2, getSnapshot2);
|
|
944
1137
|
const setPresence = room.updatePresence;
|
|
945
1138
|
return [presence, setPresence];
|
|
946
1139
|
}
|
|
@@ -949,12 +1142,12 @@ function createRoomContext(client, options) {
|
|
|
949
1142
|
}
|
|
950
1143
|
function useOthers(selector, isEqual) {
|
|
951
1144
|
const room = useRoom();
|
|
952
|
-
const
|
|
953
|
-
const
|
|
1145
|
+
const subscribe2 = room.events.others.subscribe;
|
|
1146
|
+
const getSnapshot2 = room.getOthers;
|
|
954
1147
|
const getServerSnapshot = alwaysEmptyList;
|
|
955
1148
|
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
956
|
-
|
|
957
|
-
|
|
1149
|
+
subscribe2,
|
|
1150
|
+
getSnapshot2,
|
|
958
1151
|
getServerSnapshot,
|
|
959
1152
|
_nullishCoalesce(selector, () => ( identity)),
|
|
960
1153
|
isEqual
|
|
@@ -1058,8 +1251,8 @@ function createRoomContext(client, options) {
|
|
|
1058
1251
|
}
|
|
1059
1252
|
function useSelf(maybeSelector, isEqual) {
|
|
1060
1253
|
const room = useRoom();
|
|
1061
|
-
const
|
|
1062
|
-
const
|
|
1254
|
+
const subscribe2 = room.events.self.subscribe;
|
|
1255
|
+
const getSnapshot2 = room.getSelf;
|
|
1063
1256
|
const selector = _nullishCoalesce(maybeSelector, () => ( identity));
|
|
1064
1257
|
const wrappedSelector = React2.useCallback(
|
|
1065
1258
|
(me) => me !== null ? selector(me) : null,
|
|
@@ -1067,8 +1260,8 @@ function createRoomContext(client, options) {
|
|
|
1067
1260
|
);
|
|
1068
1261
|
const getServerSnapshot = alwaysNull;
|
|
1069
1262
|
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
1070
|
-
|
|
1071
|
-
|
|
1263
|
+
subscribe2,
|
|
1264
|
+
getSnapshot2,
|
|
1072
1265
|
getServerSnapshot,
|
|
1073
1266
|
wrappedSelector,
|
|
1074
1267
|
isEqual
|
|
@@ -1076,10 +1269,10 @@ function createRoomContext(client, options) {
|
|
|
1076
1269
|
}
|
|
1077
1270
|
function useMutableStorageRoot() {
|
|
1078
1271
|
const room = useRoom();
|
|
1079
|
-
const
|
|
1080
|
-
const
|
|
1272
|
+
const subscribe2 = room.events.storageDidLoad.subscribeOnce;
|
|
1273
|
+
const getSnapshot2 = room.getStorageSnapshot;
|
|
1081
1274
|
const getServerSnapshot = alwaysNull;
|
|
1082
|
-
return
|
|
1275
|
+
return useSyncExternalStore5(subscribe2, getSnapshot2, getServerSnapshot);
|
|
1083
1276
|
}
|
|
1084
1277
|
function useStorageRoot() {
|
|
1085
1278
|
return [useMutableStorageRoot()];
|
|
@@ -1095,15 +1288,15 @@ function createRoomContext(client, options) {
|
|
|
1095
1288
|
}
|
|
1096
1289
|
function useCanUndo() {
|
|
1097
1290
|
const room = useRoom();
|
|
1098
|
-
const
|
|
1291
|
+
const subscribe2 = room.events.history.subscribe;
|
|
1099
1292
|
const canUndo = room.history.canUndo;
|
|
1100
|
-
return
|
|
1293
|
+
return useSyncExternalStore5(subscribe2, canUndo, canUndo);
|
|
1101
1294
|
}
|
|
1102
1295
|
function useCanRedo() {
|
|
1103
1296
|
const room = useRoom();
|
|
1104
|
-
const
|
|
1297
|
+
const subscribe2 = room.events.history.subscribe;
|
|
1105
1298
|
const canRedo = room.history.canRedo;
|
|
1106
|
-
return
|
|
1299
|
+
return useSyncExternalStore5(subscribe2, canRedo, canRedo);
|
|
1107
1300
|
}
|
|
1108
1301
|
function useBatch() {
|
|
1109
1302
|
return useRoom().batch;
|
|
@@ -1125,7 +1318,7 @@ function createRoomContext(client, options) {
|
|
|
1125
1318
|
function onRootChange() {
|
|
1126
1319
|
const newValue = root.get(key);
|
|
1127
1320
|
if (newValue !== curr) {
|
|
1128
|
-
_optionalChain([unsubCurr, 'optionalCall',
|
|
1321
|
+
_optionalChain([unsubCurr, 'optionalCall', _19 => _19()]);
|
|
1129
1322
|
curr = newValue;
|
|
1130
1323
|
subscribeToCurr();
|
|
1131
1324
|
rerender();
|
|
@@ -1136,7 +1329,7 @@ function createRoomContext(client, options) {
|
|
|
1136
1329
|
const unsubscribeRoot = room.subscribe(root, onRootChange);
|
|
1137
1330
|
return () => {
|
|
1138
1331
|
unsubscribeRoot();
|
|
1139
|
-
_optionalChain([unsubCurr, 'optionalCall',
|
|
1332
|
+
_optionalChain([unsubCurr, 'optionalCall', _20 => _20()]);
|
|
1140
1333
|
};
|
|
1141
1334
|
}, [rootOrNull, room, key, rerender]);
|
|
1142
1335
|
if (rootOrNull === null) {
|
|
@@ -1152,11 +1345,11 @@ function createRoomContext(client, options) {
|
|
|
1152
1345
|
(rootOrNull2) => rootOrNull2 !== null ? selector(rootOrNull2) : null,
|
|
1153
1346
|
[selector]
|
|
1154
1347
|
);
|
|
1155
|
-
const
|
|
1348
|
+
const subscribe2 = React2.useCallback(
|
|
1156
1349
|
(onStoreChange) => rootOrNull !== null ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true }) : noop2,
|
|
1157
1350
|
[room, rootOrNull]
|
|
1158
1351
|
);
|
|
1159
|
-
const
|
|
1352
|
+
const getSnapshot2 = React2.useCallback(() => {
|
|
1160
1353
|
if (rootOrNull === null) {
|
|
1161
1354
|
return null;
|
|
1162
1355
|
} else {
|
|
@@ -1167,8 +1360,8 @@ function createRoomContext(client, options) {
|
|
|
1167
1360
|
}, [rootOrNull]);
|
|
1168
1361
|
const getServerSnapshot = alwaysNull;
|
|
1169
1362
|
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
1170
|
-
|
|
1171
|
-
|
|
1363
|
+
subscribe2,
|
|
1364
|
+
getSnapshot2,
|
|
1172
1365
|
getServerSnapshot,
|
|
1173
1366
|
wrappedSelector,
|
|
1174
1367
|
isEqual
|
|
@@ -1280,59 +1473,38 @@ function createRoomContext(client, options) {
|
|
|
1280
1473
|
}
|
|
1281
1474
|
function useCreateThread() {
|
|
1282
1475
|
const room = useRoom();
|
|
1283
|
-
return
|
|
1284
|
-
(options2) => getCommentsRoom(room).createThread(options2),
|
|
1285
|
-
[room]
|
|
1286
|
-
);
|
|
1476
|
+
return getCommentsRoom(room).useCreateThread();
|
|
1287
1477
|
}
|
|
1288
1478
|
function useEditThreadMetadata() {
|
|
1289
1479
|
const room = useRoom();
|
|
1290
|
-
return
|
|
1291
|
-
(options2) => getCommentsRoom(room).editThreadMetadata(options2),
|
|
1292
|
-
[room]
|
|
1293
|
-
);
|
|
1480
|
+
return getCommentsRoom(room).useEditThreadMetadata();
|
|
1294
1481
|
}
|
|
1295
1482
|
function useAddReaction() {
|
|
1296
1483
|
const room = useRoom();
|
|
1297
|
-
return
|
|
1298
|
-
(options2) => getCommentsRoom(room).addReaction(options2),
|
|
1299
|
-
[room]
|
|
1300
|
-
);
|
|
1484
|
+
return getCommentsRoom(room).useAddReaction();
|
|
1301
1485
|
}
|
|
1302
1486
|
function useRemoveReaction() {
|
|
1303
1487
|
const room = useRoom();
|
|
1304
|
-
return
|
|
1305
|
-
(options2) => getCommentsRoom(room).removeReaction(options2),
|
|
1306
|
-
[room]
|
|
1307
|
-
);
|
|
1488
|
+
return getCommentsRoom(room).useRemoveReaction();
|
|
1308
1489
|
}
|
|
1309
1490
|
function useCreateComment() {
|
|
1310
1491
|
const room = useRoom();
|
|
1311
|
-
return
|
|
1312
|
-
(options2) => getCommentsRoom(room).createComment(options2),
|
|
1313
|
-
[room]
|
|
1314
|
-
);
|
|
1492
|
+
return getCommentsRoom(room).useCreateComment();
|
|
1315
1493
|
}
|
|
1316
1494
|
function useEditComment() {
|
|
1317
1495
|
const room = useRoom();
|
|
1318
|
-
return
|
|
1319
|
-
(options2) => getCommentsRoom(room).editComment(options2),
|
|
1320
|
-
[room]
|
|
1321
|
-
);
|
|
1496
|
+
return getCommentsRoom(room).useEditComment();
|
|
1322
1497
|
}
|
|
1323
1498
|
function useDeleteComment() {
|
|
1324
1499
|
const room = useRoom();
|
|
1325
|
-
return
|
|
1326
|
-
(options2) => getCommentsRoom(room).deleteComment(options2),
|
|
1327
|
-
[room]
|
|
1328
|
-
);
|
|
1500
|
+
return getCommentsRoom(room).useDeleteComment();
|
|
1329
1501
|
}
|
|
1330
1502
|
const { resolveUsers, resolveMentionSuggestions } = _nullishCoalesce(options, () => ( {}));
|
|
1331
1503
|
const usersCache = resolveUsers ? _core.createAsyncCache.call(void 0, async (stringifiedOptions) => {
|
|
1332
1504
|
const users = await resolveUsers(
|
|
1333
1505
|
JSON.parse(stringifiedOptions)
|
|
1334
1506
|
);
|
|
1335
|
-
return _optionalChain([users, 'optionalAccess',
|
|
1507
|
+
return _optionalChain([users, 'optionalAccess', _21 => _21[0]]);
|
|
1336
1508
|
}) : void 0;
|
|
1337
1509
|
function useUser(userId) {
|
|
1338
1510
|
const room = useRoom();
|