@liveblocks/react 1.12.0 → 2.0.0-alpha1
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/chunk-HLKYTK7G.mjs +2435 -0
- package/dist/chunk-HLKYTK7G.mjs.map +1 -0
- package/dist/chunk-RCQYZVO3.js +2435 -0
- package/dist/chunk-RCQYZVO3.js.map +1 -0
- package/dist/index.d.mts +3 -1096
- package/dist/index.d.ts +3 -1096
- package/dist/index.js +61 -2314
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +103 -2356
- package/dist/index.mjs.map +1 -1
- package/dist/suspense-9ZocWu4y.d.mts +951 -0
- package/dist/suspense-9ZocWu4y.d.ts +951 -0
- package/dist/suspense.d.mts +4 -0
- package/dist/suspense.d.ts +4 -0
- package/dist/suspense.js +110 -0
- package/dist/suspense.js.map +1 -0
- package/dist/suspense.mjs +110 -0
- package/dist/suspense.mjs.map +1 -0
- package/package.json +18 -4
- package/suspense/README.md +5 -0
- package/suspense/package.json +4 -0
package/dist/index.mjs
CHANGED
|
@@ -1,2367 +1,114 @@
|
|
|
1
|
-
|
|
1
|
+
import {
|
|
2
|
+
ClientContext,
|
|
3
|
+
ClientSideSuspense,
|
|
4
|
+
LiveblocksProvider,
|
|
5
|
+
PKG_FORMAT,
|
|
6
|
+
PKG_NAME,
|
|
7
|
+
PKG_VERSION,
|
|
8
|
+
RoomContext,
|
|
9
|
+
_RoomProvider,
|
|
10
|
+
__1,
|
|
11
|
+
__2,
|
|
12
|
+
_useAddReaction,
|
|
13
|
+
_useBroadcastEvent,
|
|
14
|
+
_useCreateThread,
|
|
15
|
+
_useEditThreadMetadata,
|
|
16
|
+
_useEventListener,
|
|
17
|
+
_useMutation,
|
|
18
|
+
_useMyPresence,
|
|
19
|
+
_useOther,
|
|
20
|
+
_useOthers,
|
|
21
|
+
_useOthersListener,
|
|
22
|
+
_useOthersMapped,
|
|
23
|
+
_useRoom,
|
|
24
|
+
_useSelf,
|
|
25
|
+
_useStorage,
|
|
26
|
+
_useStorageRoot,
|
|
27
|
+
_useThreads,
|
|
28
|
+
_useUpdateMyPresence,
|
|
29
|
+
createLiveblocksContext,
|
|
30
|
+
createRoomContext,
|
|
31
|
+
useBatch,
|
|
32
|
+
useCanRedo,
|
|
33
|
+
useCanUndo,
|
|
34
|
+
useClient,
|
|
35
|
+
useCreateComment,
|
|
36
|
+
useDeleteComment,
|
|
37
|
+
useEditComment,
|
|
38
|
+
useErrorListener,
|
|
39
|
+
useHistory,
|
|
40
|
+
useInboxNotifications,
|
|
41
|
+
useLostConnectionListener,
|
|
42
|
+
useMarkAllInboxNotificationsAsRead,
|
|
43
|
+
useMarkInboxNotificationAsRead,
|
|
44
|
+
useMarkThreadAsRead,
|
|
45
|
+
useOthersConnectionIds,
|
|
46
|
+
useRedo,
|
|
47
|
+
useRemoveReaction,
|
|
48
|
+
useRoomInfo,
|
|
49
|
+
useRoomNotificationSettings,
|
|
50
|
+
useStatus,
|
|
51
|
+
useThreadSubscription,
|
|
52
|
+
useUndo,
|
|
53
|
+
useUnreadInboxNotificationsCount,
|
|
54
|
+
useUpdateRoomNotificationSettings
|
|
55
|
+
} from "./chunk-HLKYTK7G.mjs";
|
|
2
56
|
|
|
3
57
|
// src/index.ts
|
|
4
58
|
import { detectDupes } from "@liveblocks/core";
|
|
5
|
-
|
|
6
|
-
// src/version.ts
|
|
7
|
-
var PKG_NAME = "@liveblocks/react";
|
|
8
|
-
var PKG_VERSION = "1.12.0";
|
|
9
|
-
var PKG_FORMAT = "esm";
|
|
10
|
-
|
|
11
|
-
// src/ClientSideSuspense.tsx
|
|
12
|
-
import * as React from "react";
|
|
13
|
-
function ClientSideSuspense(props) {
|
|
14
|
-
const [mounted, setMounted] = React.useState(false);
|
|
15
|
-
React.useEffect(() => {
|
|
16
|
-
setMounted(true);
|
|
17
|
-
}, []);
|
|
18
|
-
return /* @__PURE__ */ React.createElement(React.Suspense, { fallback: props.fallback }, mounted ? props.children() : props.fallback);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/liveblocks.tsx
|
|
22
|
-
import { kInternal as kInternal3, makePoller as makePoller2 } from "@liveblocks/core";
|
|
23
|
-
import { nanoid as nanoid3 } from "nanoid";
|
|
24
|
-
import React3, {
|
|
25
|
-
createContext as createContext2,
|
|
26
|
-
useCallback as useCallback3,
|
|
27
|
-
useContext as useContext3,
|
|
28
|
-
useEffect as useEffect5
|
|
29
|
-
} from "react";
|
|
30
|
-
import { useSyncExternalStore as useSyncExternalStore3 } from "use-sync-external-store/shim/index.js";
|
|
31
|
-
import { useSyncExternalStoreWithSelector as useSyncExternalStoreWithSelector2 } from "use-sync-external-store/shim/with-selector.js";
|
|
32
|
-
|
|
33
|
-
// src/comments/lib/selected-inbox-notifications.ts
|
|
34
|
-
import { applyOptimisticUpdates } from "@liveblocks/core";
|
|
35
|
-
function selectedInboxNotifications(state) {
|
|
36
|
-
const result = applyOptimisticUpdates(state);
|
|
37
|
-
return Object.values(result.inboxNotifications).sort(
|
|
38
|
-
// Sort so that the most recent notifications are first
|
|
39
|
-
(a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime()
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// src/lib/retry-error.ts
|
|
44
|
-
var MAX_ERROR_RETRY_COUNT = 5;
|
|
45
|
-
var ERROR_RETRY_INTERVAL = 5e3;
|
|
46
|
-
function retryError(action, retryCount) {
|
|
47
|
-
if (retryCount >= MAX_ERROR_RETRY_COUNT)
|
|
48
|
-
return;
|
|
49
|
-
const timeout = Math.pow(2, retryCount) * ERROR_RETRY_INTERVAL;
|
|
50
|
-
setTimeout(() => {
|
|
51
|
-
void action();
|
|
52
|
-
}, timeout);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// src/shared.ts
|
|
56
|
-
import { kInternal as kInternal2 } from "@liveblocks/core";
|
|
57
|
-
import { useCallback as useCallback2, useContext as useContext2, useEffect as useEffect4 } from "react";
|
|
58
|
-
import { useSyncExternalStore as useSyncExternalStore2 } from "use-sync-external-store/shim/index.js";
|
|
59
|
-
|
|
60
|
-
// src/room.tsx
|
|
61
59
|
import { shallow } from "@liveblocks/client";
|
|
62
|
-
import {
|
|
63
|
-
addReaction,
|
|
64
|
-
CommentsApiError,
|
|
65
|
-
console as console2,
|
|
66
|
-
deleteComment,
|
|
67
|
-
deprecateIf,
|
|
68
|
-
errorIf,
|
|
69
|
-
isLiveNode,
|
|
70
|
-
kInternal,
|
|
71
|
-
makeEventSource,
|
|
72
|
-
makePoller,
|
|
73
|
-
NotificationsApiError,
|
|
74
|
-
removeReaction,
|
|
75
|
-
ServerMsgCode,
|
|
76
|
-
stringify,
|
|
77
|
-
upsertComment
|
|
78
|
-
} from "@liveblocks/core";
|
|
79
|
-
import { nanoid as nanoid2 } from "nanoid";
|
|
80
|
-
import * as React2 from "react";
|
|
81
|
-
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector.js";
|
|
82
|
-
|
|
83
|
-
// src/comments/errors.ts
|
|
84
|
-
var CreateThreadError = class extends Error {
|
|
85
|
-
constructor(cause, context) {
|
|
86
|
-
super("Create thread failed.");
|
|
87
|
-
this.cause = cause;
|
|
88
|
-
this.context = context;
|
|
89
|
-
this.name = "CreateThreadError";
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
var EditThreadMetadataError = class extends Error {
|
|
93
|
-
constructor(cause, context) {
|
|
94
|
-
super("Edit thread metadata failed.");
|
|
95
|
-
this.cause = cause;
|
|
96
|
-
this.context = context;
|
|
97
|
-
this.name = "EditThreadMetadataError";
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
var CreateCommentError = class extends Error {
|
|
101
|
-
constructor(cause, context) {
|
|
102
|
-
super("Create comment failed.");
|
|
103
|
-
this.cause = cause;
|
|
104
|
-
this.context = context;
|
|
105
|
-
this.name = "CreateCommentError";
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
var EditCommentError = class extends Error {
|
|
109
|
-
constructor(cause, context) {
|
|
110
|
-
super("Edit comment failed.");
|
|
111
|
-
this.cause = cause;
|
|
112
|
-
this.context = context;
|
|
113
|
-
this.name = "EditCommentError";
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
var DeleteCommentError = class extends Error {
|
|
117
|
-
constructor(cause, context) {
|
|
118
|
-
super("Delete comment failed.");
|
|
119
|
-
this.cause = cause;
|
|
120
|
-
this.context = context;
|
|
121
|
-
this.name = "DeleteCommentError";
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
var AddReactionError = class extends Error {
|
|
125
|
-
constructor(cause, context) {
|
|
126
|
-
super("Add reaction failed.");
|
|
127
|
-
this.cause = cause;
|
|
128
|
-
this.context = context;
|
|
129
|
-
this.name = "AddReactionError";
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
var RemoveReactionError = class extends Error {
|
|
133
|
-
constructor(cause, context) {
|
|
134
|
-
super("Remove reaction failed.");
|
|
135
|
-
this.cause = cause;
|
|
136
|
-
this.context = context;
|
|
137
|
-
this.name = "RemoveReactionError";
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
var MarkInboxNotificationAsReadError = class extends Error {
|
|
141
|
-
constructor(cause, context) {
|
|
142
|
-
super("Mark inbox notification as read failed.");
|
|
143
|
-
this.cause = cause;
|
|
144
|
-
this.context = context;
|
|
145
|
-
this.name = "MarkInboxNotificationAsReadError";
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
var UpdateNotificationSettingsError = class extends Error {
|
|
149
|
-
constructor(cause, context) {
|
|
150
|
-
super("Update notification settings failed.");
|
|
151
|
-
this.cause = cause;
|
|
152
|
-
this.context = context;
|
|
153
|
-
this.name = "UpdateNotificationSettingsError";
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
// src/comments/lib/createIds.ts
|
|
158
|
-
import { nanoid } from "nanoid";
|
|
159
|
-
var THREAD_ID_PREFIX = "th";
|
|
160
|
-
var COMMENT_ID_PREFIX = "cm";
|
|
161
|
-
function createOptimisticId(prefix) {
|
|
162
|
-
return `${prefix}_${nanoid()}`;
|
|
163
|
-
}
|
|
164
|
-
function createThreadId() {
|
|
165
|
-
return createOptimisticId(THREAD_ID_PREFIX);
|
|
166
|
-
}
|
|
167
|
-
function createCommentId() {
|
|
168
|
-
return createOptimisticId(COMMENT_ID_PREFIX);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// src/comments/lib/select-notification-settings.ts
|
|
172
|
-
import {
|
|
173
|
-
applyOptimisticUpdates as applyOptimisticUpdates2,
|
|
174
|
-
nn
|
|
175
|
-
} from "@liveblocks/core";
|
|
176
|
-
function selectNotificationSettings(roomId, state) {
|
|
177
|
-
const { notificationSettings } = applyOptimisticUpdates2(state);
|
|
178
|
-
return nn(notificationSettings[roomId]);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// src/comments/lib/selected-threads.ts
|
|
182
|
-
import {
|
|
183
|
-
applyOptimisticUpdates as applyOptimisticUpdates3
|
|
184
|
-
} from "@liveblocks/core";
|
|
185
|
-
function selectedThreads(roomId, state, options) {
|
|
186
|
-
const result = applyOptimisticUpdates3(state);
|
|
187
|
-
const threads = Object.values(result.threads).filter((thread) => {
|
|
188
|
-
if (thread.roomId !== roomId)
|
|
189
|
-
return false;
|
|
190
|
-
if (thread.deletedAt !== void 0) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
const query = options.query;
|
|
194
|
-
if (!query)
|
|
195
|
-
return true;
|
|
196
|
-
for (const key in query.metadata) {
|
|
197
|
-
const metadataValue = thread.metadata[key];
|
|
198
|
-
const filterValue = query.metadata[key];
|
|
199
|
-
if (assertFilterIsStartsWithOperator(filterValue) && assertMetadataValueIsString(metadataValue)) {
|
|
200
|
-
if (metadataValue.startsWith(filterValue.startsWith)) {
|
|
201
|
-
return true;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
if (metadataValue !== filterValue) {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return true;
|
|
209
|
-
});
|
|
210
|
-
return threads.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
211
|
-
}
|
|
212
|
-
var assertFilterIsStartsWithOperator = (filter) => {
|
|
213
|
-
if (typeof filter === "object" && typeof filter.startsWith === "string") {
|
|
214
|
-
return true;
|
|
215
|
-
} else {
|
|
216
|
-
return false;
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
var assertMetadataValueIsString = (value) => {
|
|
220
|
-
return typeof value === "string";
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
// src/lib/use-initial.ts
|
|
224
|
-
import { useState as useState2 } from "react";
|
|
225
|
-
function useInitial(value) {
|
|
226
|
-
return useState2(value)[0];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// src/lib/use-latest.ts
|
|
230
|
-
import { useEffect as useEffect2, useRef } from "react";
|
|
231
|
-
function useLatest(value) {
|
|
232
|
-
const ref = useRef(value);
|
|
233
|
-
useEffect2(() => {
|
|
234
|
-
ref.current = value;
|
|
235
|
-
}, [value]);
|
|
236
|
-
return ref;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// src/lib/use-rerender.ts
|
|
240
|
-
import { useReducer } from "react";
|
|
241
|
-
function useRerender() {
|
|
242
|
-
const [, update] = useReducer(
|
|
243
|
-
// This implementation works by incrementing a hidden counter value that is
|
|
244
|
-
// never consumed. Simply incrementing the counter changes the component's
|
|
245
|
-
// state and, thus, trigger a re-render.
|
|
246
|
-
(x) => x + 1,
|
|
247
|
-
0
|
|
248
|
-
);
|
|
249
|
-
return update;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// src/room.tsx
|
|
253
|
-
var noop = () => {
|
|
254
|
-
};
|
|
255
|
-
var identity = (x) => x;
|
|
256
|
-
var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\u2019re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you\u2019re ready to upgrade to React 18:
|
|
257
|
-
|
|
258
|
-
import { unstable_batchedUpdates } from "react-dom"; // or "react-native"
|
|
259
|
-
|
|
260
|
-
<RoomProvider id=${JSON.stringify(
|
|
261
|
-
roomId
|
|
262
|
-
)} ... unstable_batchedUpdates={unstable_batchedUpdates}>
|
|
263
|
-
...
|
|
264
|
-
</RoomProvider>
|
|
265
|
-
|
|
266
|
-
Why? Please see https://liveblocks.io/docs/platform/troubleshooting#stale-props-zombie-child for more information`;
|
|
267
|
-
var superfluous_unstable_batchedUpdates = "You don\u2019t need to pass unstable_batchedUpdates to RoomProvider anymore, since you\u2019re on React 18+ already.";
|
|
268
|
-
function useSyncExternalStore(s, gs, gss) {
|
|
269
|
-
return useSyncExternalStoreWithSelector(s, gs, gss, identity);
|
|
270
|
-
}
|
|
271
|
-
var STABLE_EMPTY_LIST = Object.freeze([]);
|
|
272
|
-
var POLLING_INTERVAL = 5 * 60 * 1e3;
|
|
273
|
-
var MENTION_SUGGESTIONS_DEBOUNCE = 500;
|
|
274
|
-
function alwaysEmptyList() {
|
|
275
|
-
return STABLE_EMPTY_LIST;
|
|
276
|
-
}
|
|
277
|
-
function alwaysNull() {
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
function makeMutationContext(room) {
|
|
281
|
-
const errmsg = "This mutation cannot be used until connected to the Liveblocks room";
|
|
282
|
-
return {
|
|
283
|
-
get storage() {
|
|
284
|
-
const mutableRoot = room.getStorageSnapshot();
|
|
285
|
-
if (mutableRoot === null) {
|
|
286
|
-
throw new Error(errmsg);
|
|
287
|
-
}
|
|
288
|
-
return mutableRoot;
|
|
289
|
-
},
|
|
290
|
-
get self() {
|
|
291
|
-
const self = room.getSelf();
|
|
292
|
-
if (self === null) {
|
|
293
|
-
throw new Error(errmsg);
|
|
294
|
-
}
|
|
295
|
-
return self;
|
|
296
|
-
},
|
|
297
|
-
get others() {
|
|
298
|
-
const others = room.getOthers();
|
|
299
|
-
if (room.getSelf() === null) {
|
|
300
|
-
throw new Error(errmsg);
|
|
301
|
-
}
|
|
302
|
-
return others;
|
|
303
|
-
},
|
|
304
|
-
setMyPresence: room.updatePresence
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
var ContextBundle = React2.createContext(null);
|
|
308
|
-
function useRoomContextBundle() {
|
|
309
|
-
const bundle = React2.useContext(ContextBundle);
|
|
310
|
-
if (bundle === null) {
|
|
311
|
-
throw new Error("RoomProvider is missing from the React tree.");
|
|
312
|
-
}
|
|
313
|
-
return bundle;
|
|
314
|
-
}
|
|
315
|
-
function createRoomContext(client, options) {
|
|
316
|
-
if (options?.resolveUsers) {
|
|
317
|
-
throw new Error(
|
|
318
|
-
"The 'resolveUsers' option has moved to 'createClient' from '@liveblocks/client'. Please refer to our Upgrade Guide to learn more, see https://liveblocks.io/docs/platform/upgrading/1.10."
|
|
319
|
-
);
|
|
320
|
-
}
|
|
321
|
-
if (options?.resolveMentionSuggestions) {
|
|
322
|
-
throw new Error(
|
|
323
|
-
"The 'resolveMentionSuggestions' option has moved to 'createClient' from '@liveblocks/client'. Please refer to our Upgrade Guide to learn more, see https://liveblocks.io/docs/platform/upgrading/1.10."
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
const RoomContext = React2.createContext(null);
|
|
327
|
-
const commentsErrorEventSource = makeEventSource();
|
|
328
|
-
const shared = createSharedContext(client);
|
|
329
|
-
function RoomProviderOuter(props) {
|
|
330
|
-
const [cache] = React2.useState(
|
|
331
|
-
() => /* @__PURE__ */ new Map()
|
|
332
|
-
);
|
|
333
|
-
const stableEnterRoom = React2.useCallback(
|
|
334
|
-
(roomId, options2) => {
|
|
335
|
-
const cached = cache.get(roomId);
|
|
336
|
-
if (cached)
|
|
337
|
-
return cached;
|
|
338
|
-
const rv = client.enterRoom(
|
|
339
|
-
roomId,
|
|
340
|
-
options2
|
|
341
|
-
);
|
|
342
|
-
const origLeave = rv.leave;
|
|
343
|
-
rv.leave = () => {
|
|
344
|
-
origLeave();
|
|
345
|
-
cache.delete(roomId);
|
|
346
|
-
};
|
|
347
|
-
cache.set(roomId, rv);
|
|
348
|
-
return rv;
|
|
349
|
-
},
|
|
350
|
-
[cache]
|
|
351
|
-
);
|
|
352
|
-
return /* @__PURE__ */ React2.createElement(RoomProviderInner, { ...props, stableEnterRoom });
|
|
353
|
-
}
|
|
354
|
-
function RoomProviderInner(props) {
|
|
355
|
-
const { id: roomId, stableEnterRoom } = props;
|
|
356
|
-
if (process.env.NODE_ENV !== "production") {
|
|
357
|
-
if (!roomId) {
|
|
358
|
-
throw new Error(
|
|
359
|
-
"RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required"
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
if (typeof roomId !== "string") {
|
|
363
|
-
throw new Error("RoomProvider id property should be a string.");
|
|
364
|
-
}
|
|
365
|
-
const majorReactVersion = parseInt(React2.version) || 1;
|
|
366
|
-
const oldReactVersion = majorReactVersion < 18;
|
|
367
|
-
errorIf(
|
|
368
|
-
oldReactVersion && props.unstable_batchedUpdates === void 0,
|
|
369
|
-
missing_unstable_batchedUpdates(majorReactVersion, roomId)
|
|
370
|
-
);
|
|
371
|
-
deprecateIf(
|
|
372
|
-
!oldReactVersion && props.unstable_batchedUpdates !== void 0,
|
|
373
|
-
superfluous_unstable_batchedUpdates
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
const frozenProps = useInitial({
|
|
377
|
-
initialPresence: props.initialPresence,
|
|
378
|
-
initialStorage: props.initialStorage,
|
|
379
|
-
unstable_batchedUpdates: props.unstable_batchedUpdates,
|
|
380
|
-
autoConnect: props.autoConnect ?? props.shouldInitiallyConnect ?? typeof window !== "undefined"
|
|
381
|
-
});
|
|
382
|
-
const [{ room }, setRoomLeavePair] = React2.useState(
|
|
383
|
-
() => stableEnterRoom(roomId, {
|
|
384
|
-
...frozenProps,
|
|
385
|
-
autoConnect: false
|
|
386
|
-
// Deliberately using false here on the first render, see below
|
|
387
|
-
})
|
|
388
|
-
);
|
|
389
|
-
React2.useEffect(() => {
|
|
390
|
-
async function handleCommentEvent(message) {
|
|
391
|
-
const info = await room[kInternal].comments.getThread({
|
|
392
|
-
threadId: message.threadId
|
|
393
|
-
});
|
|
394
|
-
if (!info) {
|
|
395
|
-
store.deleteThread(message.threadId);
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
const { thread, inboxNotification } = info;
|
|
399
|
-
const existingThread = store.get().threads[message.threadId];
|
|
400
|
-
switch (message.type) {
|
|
401
|
-
case ServerMsgCode.COMMENT_EDITED:
|
|
402
|
-
case ServerMsgCode.THREAD_METADATA_UPDATED:
|
|
403
|
-
case ServerMsgCode.COMMENT_REACTION_ADDED:
|
|
404
|
-
case ServerMsgCode.COMMENT_REACTION_REMOVED:
|
|
405
|
-
case ServerMsgCode.COMMENT_DELETED:
|
|
406
|
-
if (!existingThread)
|
|
407
|
-
break;
|
|
408
|
-
store.updateThreadAndNotification(thread, inboxNotification);
|
|
409
|
-
break;
|
|
410
|
-
case ServerMsgCode.COMMENT_CREATED:
|
|
411
|
-
store.updateThreadAndNotification(thread, inboxNotification);
|
|
412
|
-
break;
|
|
413
|
-
default:
|
|
414
|
-
break;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
return room.events.comments.subscribe(
|
|
418
|
-
(message) => void handleCommentEvent(message)
|
|
419
|
-
);
|
|
420
|
-
}, [room]);
|
|
421
|
-
React2.useEffect(() => {
|
|
422
|
-
void getThreadsUpdates(room.id);
|
|
423
|
-
}, [room.id]);
|
|
424
|
-
React2.useEffect(() => {
|
|
425
|
-
function handleIsOnline() {
|
|
426
|
-
void getThreadsUpdates(room.id);
|
|
427
|
-
}
|
|
428
|
-
window.addEventListener("online", handleIsOnline);
|
|
429
|
-
return () => {
|
|
430
|
-
window.removeEventListener("online", handleIsOnline);
|
|
431
|
-
};
|
|
432
|
-
}, [room.id]);
|
|
433
|
-
React2.useEffect(() => {
|
|
434
|
-
const pair = stableEnterRoom(roomId, frozenProps);
|
|
435
|
-
setRoomLeavePair(pair);
|
|
436
|
-
const { room: room2, leave } = pair;
|
|
437
|
-
if (frozenProps.autoConnect) {
|
|
438
|
-
room2.connect();
|
|
439
|
-
}
|
|
440
|
-
return () => {
|
|
441
|
-
leave();
|
|
442
|
-
};
|
|
443
|
-
}, [roomId, frozenProps, stableEnterRoom]);
|
|
444
|
-
return /* @__PURE__ */ React2.createElement(RoomContext.Provider, { value: room }, /* @__PURE__ */ React2.createElement(
|
|
445
|
-
ContextBundle.Provider,
|
|
446
|
-
{
|
|
447
|
-
value: bundle
|
|
448
|
-
},
|
|
449
|
-
props.children
|
|
450
|
-
));
|
|
451
|
-
}
|
|
452
|
-
function connectionIdSelector(others) {
|
|
453
|
-
return others.map((user) => user.connectionId);
|
|
454
|
-
}
|
|
455
|
-
function useRoom() {
|
|
456
|
-
const room = React2.useContext(RoomContext);
|
|
457
|
-
if (room === null) {
|
|
458
|
-
throw new Error("RoomProvider is missing from the React tree.");
|
|
459
|
-
}
|
|
460
|
-
return room;
|
|
461
|
-
}
|
|
462
|
-
function useStatus() {
|
|
463
|
-
const room = useRoom();
|
|
464
|
-
const subscribe = room.events.status.subscribe;
|
|
465
|
-
const getSnapshot = room.getStatus;
|
|
466
|
-
const getServerSnapshot = room.getStatus;
|
|
467
|
-
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
468
|
-
}
|
|
469
|
-
function useMyPresence() {
|
|
470
|
-
const room = useRoom();
|
|
471
|
-
const subscribe = room.events.myPresence.subscribe;
|
|
472
|
-
const getSnapshot = room.getPresence;
|
|
473
|
-
const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
474
|
-
const setPresence = room.updatePresence;
|
|
475
|
-
return [presence, setPresence];
|
|
476
|
-
}
|
|
477
|
-
function useUpdateMyPresence() {
|
|
478
|
-
return useRoom().updatePresence;
|
|
479
|
-
}
|
|
480
|
-
function useOthers(selector, isEqual) {
|
|
481
|
-
const room = useRoom();
|
|
482
|
-
const subscribe = room.events.others.subscribe;
|
|
483
|
-
const getSnapshot = room.getOthers;
|
|
484
|
-
const getServerSnapshot = alwaysEmptyList;
|
|
485
|
-
return useSyncExternalStoreWithSelector(
|
|
486
|
-
subscribe,
|
|
487
|
-
getSnapshot,
|
|
488
|
-
getServerSnapshot,
|
|
489
|
-
selector ?? identity,
|
|
490
|
-
isEqual
|
|
491
|
-
);
|
|
492
|
-
}
|
|
493
|
-
function useOthersConnectionIds() {
|
|
494
|
-
return useOthers(connectionIdSelector, shallow);
|
|
495
|
-
}
|
|
496
|
-
function useOthersMapped(itemSelector, itemIsEqual) {
|
|
497
|
-
const wrappedSelector = React2.useCallback(
|
|
498
|
-
(others) => others.map(
|
|
499
|
-
(other) => [other.connectionId, itemSelector(other)]
|
|
500
|
-
),
|
|
501
|
-
[itemSelector]
|
|
502
|
-
);
|
|
503
|
-
const wrappedIsEqual = React2.useCallback(
|
|
504
|
-
(a, b) => {
|
|
505
|
-
const eq = itemIsEqual ?? Object.is;
|
|
506
|
-
return a.length === b.length && a.every((atuple, index) => {
|
|
507
|
-
const btuple = b[index];
|
|
508
|
-
return atuple[0] === btuple[0] && eq(atuple[1], btuple[1]);
|
|
509
|
-
});
|
|
510
|
-
},
|
|
511
|
-
[itemIsEqual]
|
|
512
|
-
);
|
|
513
|
-
return useOthers(wrappedSelector, wrappedIsEqual);
|
|
514
|
-
}
|
|
515
|
-
const NOT_FOUND = Symbol();
|
|
516
|
-
function useOther(connectionId, selector, isEqual) {
|
|
517
|
-
const wrappedSelector = React2.useCallback(
|
|
518
|
-
(others) => {
|
|
519
|
-
const other2 = others.find(
|
|
520
|
-
(other3) => other3.connectionId === connectionId
|
|
521
|
-
);
|
|
522
|
-
return other2 !== void 0 ? selector(other2) : NOT_FOUND;
|
|
523
|
-
},
|
|
524
|
-
[connectionId, selector]
|
|
525
|
-
);
|
|
526
|
-
const wrappedIsEqual = React2.useCallback(
|
|
527
|
-
(prev, curr) => {
|
|
528
|
-
if (prev === NOT_FOUND || curr === NOT_FOUND) {
|
|
529
|
-
return prev === curr;
|
|
530
|
-
}
|
|
531
|
-
const eq = isEqual ?? Object.is;
|
|
532
|
-
return eq(prev, curr);
|
|
533
|
-
},
|
|
534
|
-
[isEqual]
|
|
535
|
-
);
|
|
536
|
-
const other = useOthers(wrappedSelector, wrappedIsEqual);
|
|
537
|
-
if (other === NOT_FOUND) {
|
|
538
|
-
throw new Error(
|
|
539
|
-
`No such other user with connection id ${connectionId} exists`
|
|
540
|
-
);
|
|
541
|
-
}
|
|
542
|
-
return other;
|
|
543
|
-
}
|
|
544
|
-
function useBroadcastEvent() {
|
|
545
|
-
const room = useRoom();
|
|
546
|
-
return React2.useCallback(
|
|
547
|
-
(event, options2 = { shouldQueueEventIfNotReady: false }) => {
|
|
548
|
-
room.broadcastEvent(event, options2);
|
|
549
|
-
},
|
|
550
|
-
[room]
|
|
551
|
-
);
|
|
552
|
-
}
|
|
553
|
-
function useOthersListener(callback) {
|
|
554
|
-
const room = useRoom();
|
|
555
|
-
const savedCallback = useLatest(callback);
|
|
556
|
-
React2.useEffect(
|
|
557
|
-
() => room.events.others.subscribe((event) => savedCallback.current(event)),
|
|
558
|
-
[room, savedCallback]
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
function useLostConnectionListener(callback) {
|
|
562
|
-
const room = useRoom();
|
|
563
|
-
const savedCallback = useLatest(callback);
|
|
564
|
-
React2.useEffect(
|
|
565
|
-
() => room.events.lostConnection.subscribe(
|
|
566
|
-
(event) => savedCallback.current(event)
|
|
567
|
-
),
|
|
568
|
-
[room, savedCallback]
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
function useErrorListener(callback) {
|
|
572
|
-
const room = useRoom();
|
|
573
|
-
const savedCallback = useLatest(callback);
|
|
574
|
-
React2.useEffect(
|
|
575
|
-
() => room.events.error.subscribe((e) => savedCallback.current(e)),
|
|
576
|
-
[room, savedCallback]
|
|
577
|
-
);
|
|
578
|
-
}
|
|
579
|
-
function useEventListener(callback) {
|
|
580
|
-
const room = useRoom();
|
|
581
|
-
const savedCallback = useLatest(callback);
|
|
582
|
-
React2.useEffect(() => {
|
|
583
|
-
const listener = (eventData) => {
|
|
584
|
-
savedCallback.current(eventData);
|
|
585
|
-
};
|
|
586
|
-
return room.events.customEvent.subscribe(listener);
|
|
587
|
-
}, [room, savedCallback]);
|
|
588
|
-
}
|
|
589
|
-
function useSelf(maybeSelector, isEqual) {
|
|
590
|
-
const room = useRoom();
|
|
591
|
-
const subscribe = room.events.self.subscribe;
|
|
592
|
-
const getSnapshot = room.getSelf;
|
|
593
|
-
const selector = maybeSelector ?? identity;
|
|
594
|
-
const wrappedSelector = React2.useCallback(
|
|
595
|
-
(me) => me !== null ? selector(me) : null,
|
|
596
|
-
[selector]
|
|
597
|
-
);
|
|
598
|
-
const getServerSnapshot = alwaysNull;
|
|
599
|
-
return useSyncExternalStoreWithSelector(
|
|
600
|
-
subscribe,
|
|
601
|
-
getSnapshot,
|
|
602
|
-
getServerSnapshot,
|
|
603
|
-
wrappedSelector,
|
|
604
|
-
isEqual
|
|
605
|
-
);
|
|
606
|
-
}
|
|
607
|
-
function useMutableStorageRoot() {
|
|
608
|
-
const room = useRoom();
|
|
609
|
-
const subscribe = room.events.storageDidLoad.subscribeOnce;
|
|
610
|
-
const getSnapshot = room.getStorageSnapshot;
|
|
611
|
-
const getServerSnapshot = alwaysNull;
|
|
612
|
-
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
613
|
-
}
|
|
614
|
-
function useStorageRoot() {
|
|
615
|
-
return [useMutableStorageRoot()];
|
|
616
|
-
}
|
|
617
|
-
function useHistory() {
|
|
618
|
-
return useRoom().history;
|
|
619
|
-
}
|
|
620
|
-
function useUndo() {
|
|
621
|
-
return useHistory().undo;
|
|
622
|
-
}
|
|
623
|
-
function useRedo() {
|
|
624
|
-
return useHistory().redo;
|
|
625
|
-
}
|
|
626
|
-
function useCanUndo() {
|
|
627
|
-
const room = useRoom();
|
|
628
|
-
const subscribe = room.events.history.subscribe;
|
|
629
|
-
const canUndo = room.history.canUndo;
|
|
630
|
-
return useSyncExternalStore(subscribe, canUndo, canUndo);
|
|
631
|
-
}
|
|
632
|
-
function useCanRedo() {
|
|
633
|
-
const room = useRoom();
|
|
634
|
-
const subscribe = room.events.history.subscribe;
|
|
635
|
-
const canRedo = room.history.canRedo;
|
|
636
|
-
return useSyncExternalStore(subscribe, canRedo, canRedo);
|
|
637
|
-
}
|
|
638
|
-
function useBatch() {
|
|
639
|
-
return useRoom().batch;
|
|
640
|
-
}
|
|
641
|
-
function useLegacyKey(key) {
|
|
642
|
-
const room = useRoom();
|
|
643
|
-
const rootOrNull = useMutableStorageRoot();
|
|
644
|
-
const rerender = useRerender();
|
|
645
|
-
React2.useEffect(() => {
|
|
646
|
-
if (rootOrNull === null) {
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
|
-
const root = rootOrNull;
|
|
650
|
-
let unsubCurr;
|
|
651
|
-
let curr = root.get(key);
|
|
652
|
-
function subscribeToCurr() {
|
|
653
|
-
unsubCurr = isLiveNode(curr) ? room.subscribe(curr, rerender) : void 0;
|
|
654
|
-
}
|
|
655
|
-
function onRootChange() {
|
|
656
|
-
const newValue = root.get(key);
|
|
657
|
-
if (newValue !== curr) {
|
|
658
|
-
unsubCurr?.();
|
|
659
|
-
curr = newValue;
|
|
660
|
-
subscribeToCurr();
|
|
661
|
-
rerender();
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
subscribeToCurr();
|
|
665
|
-
rerender();
|
|
666
|
-
const unsubscribeRoot = room.subscribe(root, onRootChange);
|
|
667
|
-
return () => {
|
|
668
|
-
unsubscribeRoot();
|
|
669
|
-
unsubCurr?.();
|
|
670
|
-
};
|
|
671
|
-
}, [rootOrNull, room, key, rerender]);
|
|
672
|
-
if (rootOrNull === null) {
|
|
673
|
-
return null;
|
|
674
|
-
} else {
|
|
675
|
-
return rootOrNull.get(key);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
function useStorage(selector, isEqual) {
|
|
679
|
-
const room = useRoom();
|
|
680
|
-
const rootOrNull = useMutableStorageRoot();
|
|
681
|
-
const wrappedSelector = React2.useCallback(
|
|
682
|
-
(rootOrNull2) => rootOrNull2 !== null ? selector(rootOrNull2) : null,
|
|
683
|
-
[selector]
|
|
684
|
-
);
|
|
685
|
-
const subscribe = React2.useCallback(
|
|
686
|
-
(onStoreChange) => rootOrNull !== null ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true }) : noop,
|
|
687
|
-
[room, rootOrNull]
|
|
688
|
-
);
|
|
689
|
-
const getSnapshot = React2.useCallback(() => {
|
|
690
|
-
if (rootOrNull === null) {
|
|
691
|
-
return null;
|
|
692
|
-
} else {
|
|
693
|
-
const root = rootOrNull;
|
|
694
|
-
const imm = root.toImmutable();
|
|
695
|
-
return imm;
|
|
696
|
-
}
|
|
697
|
-
}, [rootOrNull]);
|
|
698
|
-
const getServerSnapshot = alwaysNull;
|
|
699
|
-
return useSyncExternalStoreWithSelector(
|
|
700
|
-
subscribe,
|
|
701
|
-
getSnapshot,
|
|
702
|
-
getServerSnapshot,
|
|
703
|
-
wrappedSelector,
|
|
704
|
-
isEqual
|
|
705
|
-
);
|
|
706
|
-
}
|
|
707
|
-
function ensureNotServerSide() {
|
|
708
|
-
if (typeof window === "undefined") {
|
|
709
|
-
throw new Error(
|
|
710
|
-
"You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr"
|
|
711
|
-
);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
function useSuspendUntilStorageLoaded() {
|
|
715
|
-
const room = useRoom();
|
|
716
|
-
if (room.getStorageSnapshot() !== null) {
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
ensureNotServerSide();
|
|
720
|
-
throw new Promise((res) => {
|
|
721
|
-
room.events.storageDidLoad.subscribeOnce(() => res());
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
function useSuspendUntilPresenceLoaded() {
|
|
725
|
-
const room = useRoom();
|
|
726
|
-
if (room.getSelf() !== null) {
|
|
727
|
-
return;
|
|
728
|
-
}
|
|
729
|
-
ensureNotServerSide();
|
|
730
|
-
throw new Promise((res) => {
|
|
731
|
-
room.events.self.subscribeOnce(() => res());
|
|
732
|
-
room.events.status.subscribeOnce(() => res());
|
|
733
|
-
});
|
|
734
|
-
}
|
|
735
|
-
function useMutation(callback, deps) {
|
|
736
|
-
const room = useRoom();
|
|
737
|
-
return React2.useMemo(
|
|
738
|
-
() => {
|
|
739
|
-
return (...args) => (
|
|
740
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
741
|
-
room.batch(
|
|
742
|
-
() => (
|
|
743
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
744
|
-
callback(
|
|
745
|
-
makeMutationContext(room),
|
|
746
|
-
...args
|
|
747
|
-
)
|
|
748
|
-
)
|
|
749
|
-
)
|
|
750
|
-
);
|
|
751
|
-
},
|
|
752
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
753
|
-
[room, ...deps]
|
|
754
|
-
);
|
|
755
|
-
}
|
|
756
|
-
function useStorageSuspense(selector, isEqual) {
|
|
757
|
-
useSuspendUntilStorageLoaded();
|
|
758
|
-
return useStorage(
|
|
759
|
-
selector,
|
|
760
|
-
isEqual
|
|
761
|
-
);
|
|
762
|
-
}
|
|
763
|
-
function useSelfSuspense(selector, isEqual) {
|
|
764
|
-
useSuspendUntilPresenceLoaded();
|
|
765
|
-
return useSelf(
|
|
766
|
-
selector,
|
|
767
|
-
isEqual
|
|
768
|
-
);
|
|
769
|
-
}
|
|
770
|
-
function useOthersSuspense(selector, isEqual) {
|
|
771
|
-
useSuspendUntilPresenceLoaded();
|
|
772
|
-
return useOthers(
|
|
773
|
-
selector,
|
|
774
|
-
isEqual
|
|
775
|
-
);
|
|
776
|
-
}
|
|
777
|
-
function useOthersConnectionIdsSuspense() {
|
|
778
|
-
useSuspendUntilPresenceLoaded();
|
|
779
|
-
return useOthersConnectionIds();
|
|
780
|
-
}
|
|
781
|
-
function useOthersMappedSuspense(itemSelector, itemIsEqual) {
|
|
782
|
-
useSuspendUntilPresenceLoaded();
|
|
783
|
-
return useOthersMapped(itemSelector, itemIsEqual);
|
|
784
|
-
}
|
|
785
|
-
function useOtherSuspense(connectionId, selector, isEqual) {
|
|
786
|
-
useSuspendUntilPresenceLoaded();
|
|
787
|
-
return useOther(connectionId, selector, isEqual);
|
|
788
|
-
}
|
|
789
|
-
function useLegacyKeySuspense(key) {
|
|
790
|
-
useSuspendUntilStorageLoaded();
|
|
791
|
-
return useLegacyKey(key);
|
|
792
|
-
}
|
|
793
|
-
const store = client[kInternal].cacheStore;
|
|
794
|
-
function onMutationFailure(innerError, optimisticUpdateId, createPublicError) {
|
|
795
|
-
store.set((state) => ({
|
|
796
|
-
...state,
|
|
797
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
798
|
-
(update) => update.id !== optimisticUpdateId
|
|
799
|
-
)
|
|
800
|
-
}));
|
|
801
|
-
if (innerError instanceof CommentsApiError) {
|
|
802
|
-
const error = handleApiError(innerError);
|
|
803
|
-
commentsErrorEventSource.notify(createPublicError(error));
|
|
804
|
-
return;
|
|
805
|
-
}
|
|
806
|
-
if (innerError instanceof NotificationsApiError) {
|
|
807
|
-
handleApiError(innerError);
|
|
808
|
-
return;
|
|
809
|
-
}
|
|
810
|
-
throw innerError;
|
|
811
|
-
}
|
|
812
|
-
const subscribersByQuery = /* @__PURE__ */ new Map();
|
|
813
|
-
const requestsByQuery = /* @__PURE__ */ new Map();
|
|
814
|
-
const poller = makePoller(refreshThreadsAndNotifications);
|
|
815
|
-
async function refreshThreadsAndNotifications() {
|
|
816
|
-
const requests = [];
|
|
817
|
-
client[kInternal].getRoomIds().map((roomId) => {
|
|
818
|
-
const room = client.getRoom(roomId);
|
|
819
|
-
if (room === null)
|
|
820
|
-
return;
|
|
821
|
-
requests.push(getThreadsUpdates(room.id));
|
|
822
|
-
});
|
|
823
|
-
await Promise.allSettled(requests);
|
|
824
|
-
}
|
|
825
|
-
function incrementQuerySubscribers(queryKey) {
|
|
826
|
-
const subscribers = subscribersByQuery.get(queryKey) ?? 0;
|
|
827
|
-
subscribersByQuery.set(queryKey, subscribers + 1);
|
|
828
|
-
poller.start(POLLING_INTERVAL);
|
|
829
|
-
}
|
|
830
|
-
function decrementQuerySubscribers(queryKey) {
|
|
831
|
-
const subscribers = subscribersByQuery.get(queryKey);
|
|
832
|
-
if (subscribers === void 0 || subscribers <= 0) {
|
|
833
|
-
console2.warn(
|
|
834
|
-
`Internal unexpected behavior. Cannot decrease subscriber count for query "${queryKey}"`
|
|
835
|
-
);
|
|
836
|
-
return;
|
|
837
|
-
}
|
|
838
|
-
subscribersByQuery.set(queryKey, subscribers - 1);
|
|
839
|
-
let totalSubscribers = 0;
|
|
840
|
-
for (const subscribers2 of subscribersByQuery.values()) {
|
|
841
|
-
totalSubscribers += subscribers2;
|
|
842
|
-
}
|
|
843
|
-
if (totalSubscribers <= 0) {
|
|
844
|
-
poller.stop();
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
async function getThreadsAndInboxNotifications(room, queryKey, options2, { retryCount } = { retryCount: 0 }) {
|
|
848
|
-
const existingRequest = requestsByQuery.get(queryKey);
|
|
849
|
-
if (existingRequest !== void 0)
|
|
850
|
-
return existingRequest;
|
|
851
|
-
const request = room[kInternal].comments.getThreads(options2);
|
|
852
|
-
requestsByQuery.set(queryKey, request);
|
|
853
|
-
store.setQueryState(queryKey, {
|
|
854
|
-
isLoading: true
|
|
855
|
-
});
|
|
856
|
-
try {
|
|
857
|
-
const result = await request;
|
|
858
|
-
store.updateThreadsAndNotifications(
|
|
859
|
-
result.threads,
|
|
860
|
-
result.inboxNotifications,
|
|
861
|
-
result.deletedThreads,
|
|
862
|
-
result.deletedInboxNotifications,
|
|
863
|
-
queryKey
|
|
864
|
-
);
|
|
865
|
-
const lastRequestedAt = lastRequestedAtByRoom.get(room.id);
|
|
866
|
-
if (lastRequestedAt === void 0 || lastRequestedAt > result.meta.requestedAt) {
|
|
867
|
-
lastRequestedAtByRoom.set(room.id, result.meta.requestedAt);
|
|
868
|
-
}
|
|
869
|
-
poller.start(POLLING_INTERVAL);
|
|
870
|
-
} catch (err) {
|
|
871
|
-
requestsByQuery.delete(queryKey);
|
|
872
|
-
retryError(() => {
|
|
873
|
-
void getThreadsAndInboxNotifications(room, queryKey, options2, {
|
|
874
|
-
retryCount: retryCount + 1
|
|
875
|
-
});
|
|
876
|
-
}, retryCount);
|
|
877
|
-
store.setQueryState(queryKey, {
|
|
878
|
-
isLoading: false,
|
|
879
|
-
error: err
|
|
880
|
-
});
|
|
881
|
-
return;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
const DEFAULT_DEDUPING_INTERVAL = 2e3;
|
|
885
|
-
const lastRequestedAtByRoom = /* @__PURE__ */ new Map();
|
|
886
|
-
const requestStatusByRoom = /* @__PURE__ */ new Map();
|
|
887
|
-
async function getThreadsUpdates(roomId) {
|
|
888
|
-
const room = client.getRoom(roomId);
|
|
889
|
-
if (room === null)
|
|
890
|
-
return;
|
|
891
|
-
const since = lastRequestedAtByRoom.get(room.id);
|
|
892
|
-
if (since === void 0)
|
|
893
|
-
return;
|
|
894
|
-
const isFetchingThreadsUpdates = requestStatusByRoom.get(room.id) ?? false;
|
|
895
|
-
if (isFetchingThreadsUpdates === true)
|
|
896
|
-
return;
|
|
897
|
-
try {
|
|
898
|
-
requestStatusByRoom.set(room.id, true);
|
|
899
|
-
const updates = await room[kInternal].comments.getThreads({ since });
|
|
900
|
-
setTimeout(() => {
|
|
901
|
-
requestStatusByRoom.set(room.id, false);
|
|
902
|
-
}, DEFAULT_DEDUPING_INTERVAL);
|
|
903
|
-
store.updateThreadsAndNotifications(
|
|
904
|
-
updates.threads,
|
|
905
|
-
updates.inboxNotifications,
|
|
906
|
-
updates.deletedThreads,
|
|
907
|
-
updates.deletedInboxNotifications
|
|
908
|
-
);
|
|
909
|
-
lastRequestedAtByRoom.set(room.id, updates.meta.requestedAt);
|
|
910
|
-
} catch (err) {
|
|
911
|
-
requestStatusByRoom.set(room.id, false);
|
|
912
|
-
return;
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
function handleScrollToCommentOnLoad(isQueryLoading, shouldScrollOnLoad, state) {
|
|
916
|
-
if (shouldScrollOnLoad === false)
|
|
917
|
-
return;
|
|
918
|
-
if (isQueryLoading === true)
|
|
919
|
-
return;
|
|
920
|
-
const isWindowDefined = typeof window !== "undefined";
|
|
921
|
-
if (!isWindowDefined)
|
|
922
|
-
return;
|
|
923
|
-
const hash = window.location.hash;
|
|
924
|
-
const commentId = hash.slice(1);
|
|
925
|
-
if (!commentId.startsWith("cm_"))
|
|
926
|
-
return;
|
|
927
|
-
const comment = document.getElementById(commentId);
|
|
928
|
-
if (comment === null)
|
|
929
|
-
return;
|
|
930
|
-
const comments = state.threads.flatMap((thread) => thread.comments);
|
|
931
|
-
const isCommentInThreads = comments.some(
|
|
932
|
-
(comment2) => comment2.id === commentId
|
|
933
|
-
);
|
|
934
|
-
if (!isCommentInThreads)
|
|
935
|
-
return;
|
|
936
|
-
comment.scrollIntoView();
|
|
937
|
-
}
|
|
938
|
-
function useThreads(options2 = {
|
|
939
|
-
query: { metadata: {} }
|
|
940
|
-
}) {
|
|
941
|
-
const { scrollOnLoad = true } = options2;
|
|
942
|
-
const room = useRoom();
|
|
943
|
-
const queryKey = React2.useMemo(
|
|
944
|
-
() => generateQueryKey(room.id, options2.query),
|
|
945
|
-
[room, options2]
|
|
946
|
-
);
|
|
947
|
-
React2.useEffect(() => {
|
|
948
|
-
void getThreadsAndInboxNotifications(room, queryKey, options2);
|
|
949
|
-
incrementQuerySubscribers(queryKey);
|
|
950
|
-
return () => decrementQuerySubscribers(queryKey);
|
|
951
|
-
}, [room, queryKey]);
|
|
952
|
-
const selector = React2.useCallback(
|
|
953
|
-
(state2) => {
|
|
954
|
-
const query = state2.queries[queryKey];
|
|
955
|
-
if (query === void 0 || query.isLoading) {
|
|
956
|
-
return {
|
|
957
|
-
isLoading: true
|
|
958
|
-
};
|
|
959
|
-
}
|
|
960
|
-
return {
|
|
961
|
-
threads: selectedThreads(room.id, state2, options2),
|
|
962
|
-
isLoading: false,
|
|
963
|
-
error: query.error
|
|
964
|
-
};
|
|
965
|
-
},
|
|
966
|
-
[room, queryKey]
|
|
967
|
-
// eslint-disable-line react-hooks/exhaustive-deps
|
|
968
|
-
);
|
|
969
|
-
const state = useSyncExternalStoreWithSelector(
|
|
970
|
-
store.subscribe,
|
|
971
|
-
store.get,
|
|
972
|
-
store.get,
|
|
973
|
-
selector
|
|
974
|
-
);
|
|
975
|
-
React2.useEffect(
|
|
976
|
-
() => {
|
|
977
|
-
if (state.isLoading === true)
|
|
978
|
-
return;
|
|
979
|
-
handleScrollToCommentOnLoad(state.isLoading, scrollOnLoad, state);
|
|
980
|
-
},
|
|
981
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to run this effect once
|
|
982
|
-
[state.isLoading]
|
|
983
|
-
);
|
|
984
|
-
return state;
|
|
985
|
-
}
|
|
986
|
-
function useThreadsSuspense(options2 = {
|
|
987
|
-
query: { metadata: {} }
|
|
988
|
-
}) {
|
|
989
|
-
const { scrollOnLoad = true } = options2;
|
|
990
|
-
const room = useRoom();
|
|
991
|
-
const queryKey = React2.useMemo(
|
|
992
|
-
() => generateQueryKey(room.id, options2.query),
|
|
993
|
-
[room, options2]
|
|
994
|
-
);
|
|
995
|
-
const query = store.get().queries[queryKey];
|
|
996
|
-
if (query === void 0 || query.isLoading) {
|
|
997
|
-
throw getThreadsAndInboxNotifications(room, queryKey, options2);
|
|
998
|
-
}
|
|
999
|
-
if (query.error) {
|
|
1000
|
-
throw query.error;
|
|
1001
|
-
}
|
|
1002
|
-
const selector = React2.useCallback(
|
|
1003
|
-
(state2) => {
|
|
1004
|
-
return {
|
|
1005
|
-
threads: selectedThreads(room.id, state2, options2),
|
|
1006
|
-
isLoading: false
|
|
1007
|
-
};
|
|
1008
|
-
},
|
|
1009
|
-
[room, queryKey]
|
|
1010
|
-
// eslint-disable-line react-hooks/exhaustive-deps
|
|
1011
|
-
);
|
|
1012
|
-
React2.useEffect(() => {
|
|
1013
|
-
incrementQuerySubscribers(queryKey);
|
|
1014
|
-
return () => {
|
|
1015
|
-
decrementQuerySubscribers(queryKey);
|
|
1016
|
-
};
|
|
1017
|
-
}, [queryKey]);
|
|
1018
|
-
const state = useSyncExternalStoreWithSelector(
|
|
1019
|
-
store.subscribe,
|
|
1020
|
-
store.get,
|
|
1021
|
-
store.get,
|
|
1022
|
-
selector
|
|
1023
|
-
);
|
|
1024
|
-
React2.useEffect(
|
|
1025
|
-
() => {
|
|
1026
|
-
handleScrollToCommentOnLoad(state.isLoading, scrollOnLoad, state);
|
|
1027
|
-
},
|
|
1028
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to run this effect once
|
|
1029
|
-
[state.isLoading]
|
|
1030
|
-
);
|
|
1031
|
-
return state;
|
|
1032
|
-
}
|
|
1033
|
-
function useCreateThread() {
|
|
1034
|
-
const room = useRoom();
|
|
1035
|
-
return React2.useCallback(
|
|
1036
|
-
(options2) => {
|
|
1037
|
-
const body = options2.body;
|
|
1038
|
-
const metadata = "metadata" in options2 ? options2.metadata : {};
|
|
1039
|
-
const threadId = createThreadId();
|
|
1040
|
-
const commentId = createCommentId();
|
|
1041
|
-
const createdAt = /* @__PURE__ */ new Date();
|
|
1042
|
-
const newComment = {
|
|
1043
|
-
id: commentId,
|
|
1044
|
-
threadId,
|
|
1045
|
-
roomId: room.id,
|
|
1046
|
-
createdAt,
|
|
1047
|
-
type: "comment",
|
|
1048
|
-
userId: getCurrentUserId(room),
|
|
1049
|
-
body,
|
|
1050
|
-
reactions: []
|
|
1051
|
-
};
|
|
1052
|
-
const newThread = {
|
|
1053
|
-
id: threadId,
|
|
1054
|
-
type: "thread",
|
|
1055
|
-
createdAt,
|
|
1056
|
-
updatedAt: createdAt,
|
|
1057
|
-
roomId: room.id,
|
|
1058
|
-
metadata,
|
|
1059
|
-
comments: [newComment]
|
|
1060
|
-
};
|
|
1061
|
-
const optimisticUpdateId = nanoid2();
|
|
1062
|
-
store.pushOptimisticUpdate({
|
|
1063
|
-
type: "create-thread",
|
|
1064
|
-
thread: newThread,
|
|
1065
|
-
id: optimisticUpdateId
|
|
1066
|
-
});
|
|
1067
|
-
room[kInternal].comments.createThread({ threadId, commentId, body, metadata }).then(
|
|
1068
|
-
(thread) => {
|
|
1069
|
-
store.set((state) => ({
|
|
1070
|
-
...state,
|
|
1071
|
-
threads: {
|
|
1072
|
-
...state.threads,
|
|
1073
|
-
[threadId]: thread
|
|
1074
|
-
},
|
|
1075
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1076
|
-
(update) => update.id !== optimisticUpdateId
|
|
1077
|
-
)
|
|
1078
|
-
}));
|
|
1079
|
-
},
|
|
1080
|
-
(err) => onMutationFailure(
|
|
1081
|
-
err,
|
|
1082
|
-
optimisticUpdateId,
|
|
1083
|
-
(err2) => new CreateThreadError(err2, {
|
|
1084
|
-
roomId: room.id,
|
|
1085
|
-
threadId,
|
|
1086
|
-
commentId,
|
|
1087
|
-
body,
|
|
1088
|
-
metadata
|
|
1089
|
-
})
|
|
1090
|
-
)
|
|
1091
|
-
);
|
|
1092
|
-
return newThread;
|
|
1093
|
-
},
|
|
1094
|
-
[room]
|
|
1095
|
-
);
|
|
1096
|
-
}
|
|
1097
|
-
function useEditThreadMetadata() {
|
|
1098
|
-
const room = useRoom();
|
|
1099
|
-
return React2.useCallback(
|
|
1100
|
-
(options2) => {
|
|
1101
|
-
if (!("metadata" in options2)) {
|
|
1102
|
-
return;
|
|
1103
|
-
}
|
|
1104
|
-
const threadId = options2.threadId;
|
|
1105
|
-
const metadata = options2.metadata;
|
|
1106
|
-
const updatedAt = /* @__PURE__ */ new Date();
|
|
1107
|
-
const optimisticUpdateId = nanoid2();
|
|
1108
|
-
store.pushOptimisticUpdate({
|
|
1109
|
-
type: "edit-thread-metadata",
|
|
1110
|
-
metadata,
|
|
1111
|
-
id: optimisticUpdateId,
|
|
1112
|
-
threadId,
|
|
1113
|
-
updatedAt
|
|
1114
|
-
});
|
|
1115
|
-
room[kInternal].comments.editThreadMetadata({ metadata, threadId }).then(
|
|
1116
|
-
(metadata2) => {
|
|
1117
|
-
store.set((state) => {
|
|
1118
|
-
const existingThread = state.threads[threadId];
|
|
1119
|
-
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1120
|
-
(update) => update.id !== optimisticUpdateId
|
|
1121
|
-
);
|
|
1122
|
-
if (existingThread === void 0) {
|
|
1123
|
-
return {
|
|
1124
|
-
...state,
|
|
1125
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1126
|
-
};
|
|
1127
|
-
}
|
|
1128
|
-
if (existingThread.deletedAt !== void 0) {
|
|
1129
|
-
return {
|
|
1130
|
-
...state,
|
|
1131
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1132
|
-
};
|
|
1133
|
-
}
|
|
1134
|
-
if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
|
|
1135
|
-
return {
|
|
1136
|
-
...state,
|
|
1137
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1138
|
-
};
|
|
1139
|
-
}
|
|
1140
|
-
return {
|
|
1141
|
-
...state,
|
|
1142
|
-
threads: {
|
|
1143
|
-
...state.threads,
|
|
1144
|
-
[threadId]: {
|
|
1145
|
-
...existingThread,
|
|
1146
|
-
metadata: metadata2
|
|
1147
|
-
}
|
|
1148
|
-
},
|
|
1149
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1150
|
-
};
|
|
1151
|
-
});
|
|
1152
|
-
},
|
|
1153
|
-
(err) => onMutationFailure(
|
|
1154
|
-
err,
|
|
1155
|
-
optimisticUpdateId,
|
|
1156
|
-
(error) => new EditThreadMetadataError(error, {
|
|
1157
|
-
roomId: room.id,
|
|
1158
|
-
threadId,
|
|
1159
|
-
metadata
|
|
1160
|
-
})
|
|
1161
|
-
)
|
|
1162
|
-
);
|
|
1163
|
-
},
|
|
1164
|
-
[room]
|
|
1165
|
-
);
|
|
1166
|
-
}
|
|
1167
|
-
function useAddReaction() {
|
|
1168
|
-
const room = useRoom();
|
|
1169
|
-
return React2.useCallback(
|
|
1170
|
-
({ threadId, commentId, emoji }) => {
|
|
1171
|
-
const createdAt = /* @__PURE__ */ new Date();
|
|
1172
|
-
const userId = getCurrentUserId(room);
|
|
1173
|
-
const optimisticUpdateId = nanoid2();
|
|
1174
|
-
store.pushOptimisticUpdate({
|
|
1175
|
-
type: "add-reaction",
|
|
1176
|
-
threadId,
|
|
1177
|
-
commentId,
|
|
1178
|
-
reaction: {
|
|
1179
|
-
emoji,
|
|
1180
|
-
userId,
|
|
1181
|
-
createdAt
|
|
1182
|
-
},
|
|
1183
|
-
id: optimisticUpdateId
|
|
1184
|
-
});
|
|
1185
|
-
room[kInternal].comments.addReaction({ threadId, commentId, emoji }).then(
|
|
1186
|
-
(addedReaction) => {
|
|
1187
|
-
store.set((state) => {
|
|
1188
|
-
const existingThread = state.threads[threadId];
|
|
1189
|
-
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1190
|
-
(update) => update.id !== optimisticUpdateId
|
|
1191
|
-
);
|
|
1192
|
-
if (existingThread === void 0) {
|
|
1193
|
-
return {
|
|
1194
|
-
...state,
|
|
1195
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1196
|
-
};
|
|
1197
|
-
}
|
|
1198
|
-
return {
|
|
1199
|
-
...state,
|
|
1200
|
-
threads: {
|
|
1201
|
-
...state.threads,
|
|
1202
|
-
[threadId]: addReaction(
|
|
1203
|
-
existingThread,
|
|
1204
|
-
commentId,
|
|
1205
|
-
addedReaction
|
|
1206
|
-
)
|
|
1207
|
-
},
|
|
1208
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1209
|
-
};
|
|
1210
|
-
});
|
|
1211
|
-
},
|
|
1212
|
-
(err) => onMutationFailure(
|
|
1213
|
-
err,
|
|
1214
|
-
optimisticUpdateId,
|
|
1215
|
-
(error) => new AddReactionError(error, {
|
|
1216
|
-
roomId: room.id,
|
|
1217
|
-
threadId,
|
|
1218
|
-
commentId,
|
|
1219
|
-
emoji
|
|
1220
|
-
})
|
|
1221
|
-
)
|
|
1222
|
-
);
|
|
1223
|
-
},
|
|
1224
|
-
[room]
|
|
1225
|
-
);
|
|
1226
|
-
}
|
|
1227
|
-
function useRemoveReaction() {
|
|
1228
|
-
const room = useRoom();
|
|
1229
|
-
return React2.useCallback(
|
|
1230
|
-
({ threadId, commentId, emoji }) => {
|
|
1231
|
-
const userId = getCurrentUserId(room);
|
|
1232
|
-
const removedAt = /* @__PURE__ */ new Date();
|
|
1233
|
-
const optimisticUpdateId = nanoid2();
|
|
1234
|
-
store.pushOptimisticUpdate({
|
|
1235
|
-
type: "remove-reaction",
|
|
1236
|
-
threadId,
|
|
1237
|
-
commentId,
|
|
1238
|
-
emoji,
|
|
1239
|
-
userId,
|
|
1240
|
-
removedAt,
|
|
1241
|
-
id: optimisticUpdateId
|
|
1242
|
-
});
|
|
1243
|
-
room[kInternal].comments.removeReaction({ threadId, commentId, emoji }).then(
|
|
1244
|
-
() => {
|
|
1245
|
-
store.set((state) => {
|
|
1246
|
-
const existingThread = state.threads[threadId];
|
|
1247
|
-
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1248
|
-
(update) => update.id !== optimisticUpdateId
|
|
1249
|
-
);
|
|
1250
|
-
if (existingThread === void 0) {
|
|
1251
|
-
return {
|
|
1252
|
-
...state,
|
|
1253
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1254
|
-
};
|
|
1255
|
-
}
|
|
1256
|
-
return {
|
|
1257
|
-
...state,
|
|
1258
|
-
threads: {
|
|
1259
|
-
...state.threads,
|
|
1260
|
-
[threadId]: removeReaction(
|
|
1261
|
-
existingThread,
|
|
1262
|
-
commentId,
|
|
1263
|
-
emoji,
|
|
1264
|
-
userId,
|
|
1265
|
-
removedAt
|
|
1266
|
-
)
|
|
1267
|
-
},
|
|
1268
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1269
|
-
};
|
|
1270
|
-
});
|
|
1271
|
-
},
|
|
1272
|
-
(err) => onMutationFailure(
|
|
1273
|
-
err,
|
|
1274
|
-
optimisticUpdateId,
|
|
1275
|
-
(error) => new RemoveReactionError(error, {
|
|
1276
|
-
roomId: room.id,
|
|
1277
|
-
threadId,
|
|
1278
|
-
commentId,
|
|
1279
|
-
emoji
|
|
1280
|
-
})
|
|
1281
|
-
)
|
|
1282
|
-
);
|
|
1283
|
-
},
|
|
1284
|
-
[room]
|
|
1285
|
-
);
|
|
1286
|
-
}
|
|
1287
|
-
function useCreateComment() {
|
|
1288
|
-
const room = useRoom();
|
|
1289
|
-
return React2.useCallback(
|
|
1290
|
-
({ threadId, body }) => {
|
|
1291
|
-
const commentId = createCommentId();
|
|
1292
|
-
const createdAt = /* @__PURE__ */ new Date();
|
|
1293
|
-
const comment = {
|
|
1294
|
-
id: commentId,
|
|
1295
|
-
threadId,
|
|
1296
|
-
roomId: room.id,
|
|
1297
|
-
type: "comment",
|
|
1298
|
-
createdAt,
|
|
1299
|
-
userId: getCurrentUserId(room),
|
|
1300
|
-
body,
|
|
1301
|
-
reactions: []
|
|
1302
|
-
};
|
|
1303
|
-
const optimisticUpdateId = nanoid2();
|
|
1304
|
-
store.pushOptimisticUpdate({
|
|
1305
|
-
type: "create-comment",
|
|
1306
|
-
comment,
|
|
1307
|
-
id: optimisticUpdateId
|
|
1308
|
-
});
|
|
1309
|
-
room[kInternal].comments.createComment({ threadId, commentId, body }).then(
|
|
1310
|
-
(newComment) => {
|
|
1311
|
-
store.set((state) => {
|
|
1312
|
-
const existingThread = state.threads[threadId];
|
|
1313
|
-
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1314
|
-
(update) => update.id !== optimisticUpdateId
|
|
1315
|
-
);
|
|
1316
|
-
if (existingThread === void 0) {
|
|
1317
|
-
return {
|
|
1318
|
-
...state,
|
|
1319
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1320
|
-
};
|
|
1321
|
-
}
|
|
1322
|
-
const inboxNotification = Object.values(
|
|
1323
|
-
state.inboxNotifications
|
|
1324
|
-
).find(
|
|
1325
|
-
(notification) => notification.kind === "thread" && notification.threadId === threadId
|
|
1326
|
-
);
|
|
1327
|
-
const updatedInboxNotifications = inboxNotification !== void 0 ? {
|
|
1328
|
-
...state.inboxNotifications,
|
|
1329
|
-
[inboxNotification.id]: {
|
|
1330
|
-
...inboxNotification,
|
|
1331
|
-
notifiedAt: newComment.createdAt,
|
|
1332
|
-
readAt: newComment.createdAt
|
|
1333
|
-
}
|
|
1334
|
-
} : state.inboxNotifications;
|
|
1335
|
-
return {
|
|
1336
|
-
...state,
|
|
1337
|
-
threads: {
|
|
1338
|
-
...state.threads,
|
|
1339
|
-
[threadId]: upsertComment(existingThread, newComment)
|
|
1340
|
-
// Upsert the new comment into the thread comments list (if applicable)
|
|
1341
|
-
},
|
|
1342
|
-
inboxNotifications: updatedInboxNotifications,
|
|
1343
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1344
|
-
};
|
|
1345
|
-
});
|
|
1346
|
-
},
|
|
1347
|
-
(err) => onMutationFailure(
|
|
1348
|
-
err,
|
|
1349
|
-
optimisticUpdateId,
|
|
1350
|
-
(err2) => new CreateCommentError(err2, {
|
|
1351
|
-
roomId: room.id,
|
|
1352
|
-
threadId,
|
|
1353
|
-
commentId,
|
|
1354
|
-
body
|
|
1355
|
-
})
|
|
1356
|
-
)
|
|
1357
|
-
);
|
|
1358
|
-
return comment;
|
|
1359
|
-
},
|
|
1360
|
-
[room]
|
|
1361
|
-
);
|
|
1362
|
-
}
|
|
1363
|
-
function useEditComment() {
|
|
1364
|
-
const room = useRoom();
|
|
1365
|
-
return React2.useCallback(
|
|
1366
|
-
({ threadId, commentId, body }) => {
|
|
1367
|
-
const editedAt = /* @__PURE__ */ new Date();
|
|
1368
|
-
const optimisticUpdateId = nanoid2();
|
|
1369
|
-
const thread = store.get().threads[threadId];
|
|
1370
|
-
if (thread === void 0) {
|
|
1371
|
-
console2.warn(
|
|
1372
|
-
`Internal unexpected behavior. Cannot edit comment in thread "${threadId}" because the thread does not exist in the cache.`
|
|
1373
|
-
);
|
|
1374
|
-
return;
|
|
1375
|
-
}
|
|
1376
|
-
const comment = thread.comments.find(
|
|
1377
|
-
(comment2) => comment2.id === commentId
|
|
1378
|
-
);
|
|
1379
|
-
if (comment === void 0 || comment.deletedAt !== void 0) {
|
|
1380
|
-
console2.warn(
|
|
1381
|
-
`Internal unexpected behavior. Cannot edit comment "${commentId}" in thread "${threadId}" because the comment does not exist in the cache.`
|
|
1382
|
-
);
|
|
1383
|
-
return;
|
|
1384
|
-
}
|
|
1385
|
-
store.pushOptimisticUpdate({
|
|
1386
|
-
type: "edit-comment",
|
|
1387
|
-
comment: {
|
|
1388
|
-
...comment,
|
|
1389
|
-
editedAt,
|
|
1390
|
-
body
|
|
1391
|
-
},
|
|
1392
|
-
id: optimisticUpdateId
|
|
1393
|
-
});
|
|
1394
|
-
room[kInternal].comments.editComment({ threadId, commentId, body }).then(
|
|
1395
|
-
(editedComment) => {
|
|
1396
|
-
store.set((state) => {
|
|
1397
|
-
const existingThread = state.threads[threadId];
|
|
1398
|
-
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1399
|
-
(update) => update.id !== optimisticUpdateId
|
|
1400
|
-
);
|
|
1401
|
-
if (existingThread === void 0) {
|
|
1402
|
-
return {
|
|
1403
|
-
...state,
|
|
1404
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1405
|
-
};
|
|
1406
|
-
}
|
|
1407
|
-
return {
|
|
1408
|
-
...state,
|
|
1409
|
-
threads: {
|
|
1410
|
-
...state.threads,
|
|
1411
|
-
[threadId]: upsertComment(existingThread, editedComment)
|
|
1412
|
-
// Upsert the edited comment into the thread comments list (if applicable)
|
|
1413
|
-
},
|
|
1414
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1415
|
-
};
|
|
1416
|
-
});
|
|
1417
|
-
},
|
|
1418
|
-
(err) => onMutationFailure(
|
|
1419
|
-
err,
|
|
1420
|
-
optimisticUpdateId,
|
|
1421
|
-
(error) => new EditCommentError(error, {
|
|
1422
|
-
roomId: room.id,
|
|
1423
|
-
threadId,
|
|
1424
|
-
commentId,
|
|
1425
|
-
body
|
|
1426
|
-
})
|
|
1427
|
-
)
|
|
1428
|
-
);
|
|
1429
|
-
},
|
|
1430
|
-
[room]
|
|
1431
|
-
);
|
|
1432
|
-
}
|
|
1433
|
-
function useDeleteComment() {
|
|
1434
|
-
const room = useRoom();
|
|
1435
|
-
return React2.useCallback(
|
|
1436
|
-
({ threadId, commentId }) => {
|
|
1437
|
-
const deletedAt = /* @__PURE__ */ new Date();
|
|
1438
|
-
const optimisticUpdateId = nanoid2();
|
|
1439
|
-
store.pushOptimisticUpdate({
|
|
1440
|
-
type: "delete-comment",
|
|
1441
|
-
threadId,
|
|
1442
|
-
commentId,
|
|
1443
|
-
deletedAt,
|
|
1444
|
-
id: optimisticUpdateId
|
|
1445
|
-
});
|
|
1446
|
-
room[kInternal].comments.deleteComment({ threadId, commentId }).then(
|
|
1447
|
-
() => {
|
|
1448
|
-
store.set((state) => {
|
|
1449
|
-
const existingThread = state.threads[threadId];
|
|
1450
|
-
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1451
|
-
(update) => update.id !== optimisticUpdateId
|
|
1452
|
-
);
|
|
1453
|
-
if (existingThread === void 0) {
|
|
1454
|
-
return {
|
|
1455
|
-
...state,
|
|
1456
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1457
|
-
};
|
|
1458
|
-
}
|
|
1459
|
-
return {
|
|
1460
|
-
...state,
|
|
1461
|
-
threads: {
|
|
1462
|
-
...state.threads,
|
|
1463
|
-
[threadId]: deleteComment(
|
|
1464
|
-
existingThread,
|
|
1465
|
-
commentId,
|
|
1466
|
-
deletedAt
|
|
1467
|
-
)
|
|
1468
|
-
},
|
|
1469
|
-
optimisticUpdates: updatedOptimisticUpdates
|
|
1470
|
-
};
|
|
1471
|
-
});
|
|
1472
|
-
},
|
|
1473
|
-
(err) => onMutationFailure(
|
|
1474
|
-
err,
|
|
1475
|
-
optimisticUpdateId,
|
|
1476
|
-
(error) => new DeleteCommentError(error, {
|
|
1477
|
-
roomId: room.id,
|
|
1478
|
-
threadId,
|
|
1479
|
-
commentId
|
|
1480
|
-
})
|
|
1481
|
-
)
|
|
1482
|
-
);
|
|
1483
|
-
},
|
|
1484
|
-
[room]
|
|
1485
|
-
);
|
|
1486
|
-
}
|
|
1487
|
-
const resolveMentionSuggestions = client[kInternal].resolveMentionSuggestions;
|
|
1488
|
-
const mentionSuggestionsCache = /* @__PURE__ */ new Map();
|
|
1489
|
-
function useMentionSuggestions(search) {
|
|
1490
|
-
const room = useRoom();
|
|
1491
|
-
const [mentionSuggestions, setMentionSuggestions] = React2.useState();
|
|
1492
|
-
const lastInvokedAt = React2.useRef();
|
|
1493
|
-
React2.useEffect(() => {
|
|
1494
|
-
if (search === void 0 || !resolveMentionSuggestions) {
|
|
1495
|
-
return;
|
|
1496
|
-
}
|
|
1497
|
-
const resolveMentionSuggestionsArgs = { text: search, roomId: room.id };
|
|
1498
|
-
const mentionSuggestionsCacheKey = stringify(
|
|
1499
|
-
resolveMentionSuggestionsArgs
|
|
1500
|
-
);
|
|
1501
|
-
let debounceTimeout;
|
|
1502
|
-
let isCanceled = false;
|
|
1503
|
-
const getMentionSuggestions = async () => {
|
|
1504
|
-
try {
|
|
1505
|
-
lastInvokedAt.current = performance.now();
|
|
1506
|
-
const mentionSuggestions2 = await resolveMentionSuggestions(
|
|
1507
|
-
resolveMentionSuggestionsArgs
|
|
1508
|
-
);
|
|
1509
|
-
if (!isCanceled) {
|
|
1510
|
-
setMentionSuggestions(mentionSuggestions2);
|
|
1511
|
-
mentionSuggestionsCache.set(
|
|
1512
|
-
mentionSuggestionsCacheKey,
|
|
1513
|
-
mentionSuggestions2
|
|
1514
|
-
);
|
|
1515
|
-
}
|
|
1516
|
-
} catch (error) {
|
|
1517
|
-
console2.error(error?.message);
|
|
1518
|
-
}
|
|
1519
|
-
};
|
|
1520
|
-
if (mentionSuggestionsCache.has(mentionSuggestionsCacheKey)) {
|
|
1521
|
-
setMentionSuggestions(
|
|
1522
|
-
mentionSuggestionsCache.get(mentionSuggestionsCacheKey)
|
|
1523
|
-
);
|
|
1524
|
-
} else if (!lastInvokedAt.current || Math.abs(performance.now() - lastInvokedAt.current) > MENTION_SUGGESTIONS_DEBOUNCE) {
|
|
1525
|
-
void getMentionSuggestions();
|
|
1526
|
-
} else {
|
|
1527
|
-
debounceTimeout = window.setTimeout(() => {
|
|
1528
|
-
void getMentionSuggestions();
|
|
1529
|
-
}, MENTION_SUGGESTIONS_DEBOUNCE);
|
|
1530
|
-
}
|
|
1531
|
-
return () => {
|
|
1532
|
-
isCanceled = true;
|
|
1533
|
-
window.clearTimeout(debounceTimeout);
|
|
1534
|
-
};
|
|
1535
|
-
}, [room.id, search]);
|
|
1536
|
-
return mentionSuggestions;
|
|
1537
|
-
}
|
|
1538
|
-
function useThreadSubscription(threadId) {
|
|
1539
|
-
const selector = React2.useCallback(
|
|
1540
|
-
(state) => {
|
|
1541
|
-
const inboxNotification = selectedInboxNotifications(state).find(
|
|
1542
|
-
(inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
|
|
1543
|
-
);
|
|
1544
|
-
const thread = state.threads[threadId];
|
|
1545
|
-
if (inboxNotification === void 0 || thread === void 0) {
|
|
1546
|
-
return {
|
|
1547
|
-
status: "not-subscribed"
|
|
1548
|
-
};
|
|
1549
|
-
}
|
|
1550
|
-
return {
|
|
1551
|
-
status: "subscribed",
|
|
1552
|
-
unreadSince: inboxNotification.readAt
|
|
1553
|
-
};
|
|
1554
|
-
},
|
|
1555
|
-
[threadId]
|
|
1556
|
-
);
|
|
1557
|
-
return useSyncExternalStoreWithSelector(
|
|
1558
|
-
store.subscribe,
|
|
1559
|
-
store.get,
|
|
1560
|
-
store.get,
|
|
1561
|
-
selector
|
|
1562
|
-
);
|
|
1563
|
-
}
|
|
1564
|
-
function useMarkThreadAsRead() {
|
|
1565
|
-
const room = useRoom();
|
|
1566
|
-
return React2.useCallback(
|
|
1567
|
-
(threadId) => {
|
|
1568
|
-
const inboxNotification = Object.values(
|
|
1569
|
-
store.get().inboxNotifications
|
|
1570
|
-
).find(
|
|
1571
|
-
(inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
|
|
1572
|
-
);
|
|
1573
|
-
if (!inboxNotification)
|
|
1574
|
-
return;
|
|
1575
|
-
const optimisticUpdateId = nanoid2();
|
|
1576
|
-
const now = /* @__PURE__ */ new Date();
|
|
1577
|
-
store.pushOptimisticUpdate({
|
|
1578
|
-
type: "mark-inbox-notification-as-read",
|
|
1579
|
-
id: optimisticUpdateId,
|
|
1580
|
-
inboxNotificationId: inboxNotification.id,
|
|
1581
|
-
readAt: now
|
|
1582
|
-
});
|
|
1583
|
-
room[kInternal].notifications.markInboxNotificationAsRead(inboxNotification.id).then(
|
|
1584
|
-
() => {
|
|
1585
|
-
store.set((state) => ({
|
|
1586
|
-
...state,
|
|
1587
|
-
inboxNotifications: {
|
|
1588
|
-
...state.inboxNotifications,
|
|
1589
|
-
[inboxNotification.id]: {
|
|
1590
|
-
...inboxNotification,
|
|
1591
|
-
readAt: now
|
|
1592
|
-
}
|
|
1593
|
-
},
|
|
1594
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1595
|
-
(update) => update.id !== optimisticUpdateId
|
|
1596
|
-
)
|
|
1597
|
-
}));
|
|
1598
|
-
},
|
|
1599
|
-
(err) => {
|
|
1600
|
-
onMutationFailure(
|
|
1601
|
-
err,
|
|
1602
|
-
optimisticUpdateId,
|
|
1603
|
-
(error) => new MarkInboxNotificationAsReadError(error, {
|
|
1604
|
-
inboxNotificationId: inboxNotification.id
|
|
1605
|
-
})
|
|
1606
|
-
);
|
|
1607
|
-
return;
|
|
1608
|
-
}
|
|
1609
|
-
);
|
|
1610
|
-
},
|
|
1611
|
-
[room]
|
|
1612
|
-
);
|
|
1613
|
-
}
|
|
1614
|
-
function makeNotificationSettingsQueryKey(roomId) {
|
|
1615
|
-
return `${roomId}:NOTIFICATION_SETTINGS`;
|
|
1616
|
-
}
|
|
1617
|
-
async function getInboxNotificationSettings(room, queryKey, { retryCount } = { retryCount: 0 }) {
|
|
1618
|
-
const existingRequest = requestsByQuery.get(queryKey);
|
|
1619
|
-
if (existingRequest !== void 0)
|
|
1620
|
-
return existingRequest;
|
|
1621
|
-
try {
|
|
1622
|
-
const request = room[kInternal].notifications.getRoomNotificationSettings();
|
|
1623
|
-
requestsByQuery.set(queryKey, request);
|
|
1624
|
-
store.setQueryState(queryKey, {
|
|
1625
|
-
isLoading: true
|
|
1626
|
-
});
|
|
1627
|
-
const settings = await request;
|
|
1628
|
-
store.updateRoomInboxNotificationSettings(room.id, settings, queryKey);
|
|
1629
|
-
} catch (err) {
|
|
1630
|
-
requestsByQuery.delete(queryKey);
|
|
1631
|
-
retryError(() => {
|
|
1632
|
-
void getInboxNotificationSettings(room, queryKey, {
|
|
1633
|
-
retryCount: retryCount + 1
|
|
1634
|
-
});
|
|
1635
|
-
}, retryCount);
|
|
1636
|
-
store.setQueryState(queryKey, {
|
|
1637
|
-
isLoading: false,
|
|
1638
|
-
error: err
|
|
1639
|
-
});
|
|
1640
|
-
return;
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
function useRoomNotificationSettings() {
|
|
1644
|
-
const room = useRoom();
|
|
1645
|
-
React2.useEffect(() => {
|
|
1646
|
-
const queryKey = makeNotificationSettingsQueryKey(room.id);
|
|
1647
|
-
void getInboxNotificationSettings(room, queryKey);
|
|
1648
|
-
}, [room]);
|
|
1649
|
-
const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
|
|
1650
|
-
const selector = React2.useCallback(
|
|
1651
|
-
(state) => {
|
|
1652
|
-
const query = state.queries[makeNotificationSettingsQueryKey(room.id)];
|
|
1653
|
-
if (query === void 0 || query.isLoading) {
|
|
1654
|
-
return { isLoading: true };
|
|
1655
|
-
}
|
|
1656
|
-
if (query.error !== void 0) {
|
|
1657
|
-
return { isLoading: false, error: query.error };
|
|
1658
|
-
}
|
|
1659
|
-
return {
|
|
1660
|
-
isLoading: false,
|
|
1661
|
-
settings: selectNotificationSettings(room.id, state)
|
|
1662
|
-
};
|
|
1663
|
-
},
|
|
1664
|
-
[room]
|
|
1665
|
-
);
|
|
1666
|
-
const settings = useSyncExternalStoreWithSelector(
|
|
1667
|
-
store.subscribe,
|
|
1668
|
-
store.get,
|
|
1669
|
-
store.get,
|
|
1670
|
-
selector
|
|
1671
|
-
);
|
|
1672
|
-
return React2.useMemo(() => {
|
|
1673
|
-
return [settings, updateRoomNotificationSettings];
|
|
1674
|
-
}, [settings, updateRoomNotificationSettings]);
|
|
1675
|
-
}
|
|
1676
|
-
function useRoomNotificationSettingsSuspense() {
|
|
1677
|
-
const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
|
|
1678
|
-
const room = useRoom();
|
|
1679
|
-
const queryKey = makeNotificationSettingsQueryKey(room.id);
|
|
1680
|
-
const query = store.get().queries[queryKey];
|
|
1681
|
-
if (query === void 0 || query.isLoading) {
|
|
1682
|
-
throw getInboxNotificationSettings(room, queryKey);
|
|
1683
|
-
}
|
|
1684
|
-
if (query.error) {
|
|
1685
|
-
throw query.error;
|
|
1686
|
-
}
|
|
1687
|
-
const selector = React2.useCallback(
|
|
1688
|
-
(state) => {
|
|
1689
|
-
return {
|
|
1690
|
-
isLoading: false,
|
|
1691
|
-
settings: selectNotificationSettings(room.id, state)
|
|
1692
|
-
};
|
|
1693
|
-
},
|
|
1694
|
-
[room]
|
|
1695
|
-
);
|
|
1696
|
-
const settings = useSyncExternalStoreWithSelector(
|
|
1697
|
-
store.subscribe,
|
|
1698
|
-
store.get,
|
|
1699
|
-
store.get,
|
|
1700
|
-
selector
|
|
1701
|
-
);
|
|
1702
|
-
return React2.useMemo(() => {
|
|
1703
|
-
return [settings, updateRoomNotificationSettings];
|
|
1704
|
-
}, [settings, updateRoomNotificationSettings]);
|
|
1705
|
-
}
|
|
1706
|
-
function useUpdateRoomNotificationSettings() {
|
|
1707
|
-
const room = useRoom();
|
|
1708
|
-
return React2.useCallback(
|
|
1709
|
-
(settings) => {
|
|
1710
|
-
const optimisticUpdateId = nanoid2();
|
|
1711
|
-
store.pushOptimisticUpdate({
|
|
1712
|
-
id: optimisticUpdateId,
|
|
1713
|
-
type: "update-notification-settings",
|
|
1714
|
-
roomId: room.id,
|
|
1715
|
-
settings
|
|
1716
|
-
});
|
|
1717
|
-
room[kInternal].notifications.updateRoomNotificationSettings(settings).then(
|
|
1718
|
-
(settings2) => {
|
|
1719
|
-
store.set((state) => ({
|
|
1720
|
-
...state,
|
|
1721
|
-
notificationSettings: {
|
|
1722
|
-
[room.id]: settings2
|
|
1723
|
-
},
|
|
1724
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1725
|
-
(update) => update.id !== optimisticUpdateId
|
|
1726
|
-
)
|
|
1727
|
-
}));
|
|
1728
|
-
},
|
|
1729
|
-
(err) => onMutationFailure(
|
|
1730
|
-
err,
|
|
1731
|
-
optimisticUpdateId,
|
|
1732
|
-
(error) => new UpdateNotificationSettingsError(error, {
|
|
1733
|
-
roomId: room.id
|
|
1734
|
-
})
|
|
1735
|
-
)
|
|
1736
|
-
);
|
|
1737
|
-
},
|
|
1738
|
-
[room]
|
|
1739
|
-
);
|
|
1740
|
-
}
|
|
1741
|
-
function useCurrentUserId() {
|
|
1742
|
-
return useSelf((user) => typeof user.id === "string" ? user.id : null);
|
|
1743
|
-
}
|
|
1744
|
-
const bundle = {
|
|
1745
|
-
RoomContext,
|
|
1746
|
-
RoomProvider: RoomProviderOuter,
|
|
1747
|
-
useRoom,
|
|
1748
|
-
useStatus,
|
|
1749
|
-
useBatch,
|
|
1750
|
-
useBroadcastEvent,
|
|
1751
|
-
useOthersListener,
|
|
1752
|
-
useLostConnectionListener,
|
|
1753
|
-
useErrorListener,
|
|
1754
|
-
useEventListener,
|
|
1755
|
-
useHistory,
|
|
1756
|
-
useUndo,
|
|
1757
|
-
useRedo,
|
|
1758
|
-
useCanRedo,
|
|
1759
|
-
useCanUndo,
|
|
1760
|
-
// These are just aliases. The passed-in key will define their return values.
|
|
1761
|
-
useList: useLegacyKey,
|
|
1762
|
-
useMap: useLegacyKey,
|
|
1763
|
-
useObject: useLegacyKey,
|
|
1764
|
-
useStorageRoot,
|
|
1765
|
-
useStorage,
|
|
1766
|
-
useSelf,
|
|
1767
|
-
useMyPresence,
|
|
1768
|
-
useUpdateMyPresence,
|
|
1769
|
-
useOthers,
|
|
1770
|
-
useOthersMapped,
|
|
1771
|
-
useOthersConnectionIds,
|
|
1772
|
-
useOther,
|
|
1773
|
-
useMutation,
|
|
1774
|
-
useThreads,
|
|
1775
|
-
useCreateThread,
|
|
1776
|
-
useEditThreadMetadata,
|
|
1777
|
-
useCreateComment,
|
|
1778
|
-
useEditComment,
|
|
1779
|
-
useDeleteComment,
|
|
1780
|
-
useAddReaction,
|
|
1781
|
-
useRemoveReaction,
|
|
1782
|
-
useMarkThreadAsRead,
|
|
1783
|
-
useThreadSubscription,
|
|
1784
|
-
useRoomNotificationSettings,
|
|
1785
|
-
useUpdateRoomNotificationSettings,
|
|
1786
|
-
...shared,
|
|
1787
|
-
suspense: {
|
|
1788
|
-
RoomContext,
|
|
1789
|
-
RoomProvider: RoomProviderOuter,
|
|
1790
|
-
useRoom,
|
|
1791
|
-
useStatus,
|
|
1792
|
-
useBatch,
|
|
1793
|
-
useBroadcastEvent,
|
|
1794
|
-
useOthersListener,
|
|
1795
|
-
useLostConnectionListener,
|
|
1796
|
-
useErrorListener,
|
|
1797
|
-
useEventListener,
|
|
1798
|
-
useHistory,
|
|
1799
|
-
useUndo,
|
|
1800
|
-
useRedo,
|
|
1801
|
-
useCanRedo,
|
|
1802
|
-
useCanUndo,
|
|
1803
|
-
// Legacy hooks
|
|
1804
|
-
useList: useLegacyKeySuspense,
|
|
1805
|
-
useMap: useLegacyKeySuspense,
|
|
1806
|
-
useObject: useLegacyKeySuspense,
|
|
1807
|
-
useStorageRoot,
|
|
1808
|
-
useStorage: useStorageSuspense,
|
|
1809
|
-
useSelf: useSelfSuspense,
|
|
1810
|
-
useMyPresence,
|
|
1811
|
-
useUpdateMyPresence,
|
|
1812
|
-
useOthers: useOthersSuspense,
|
|
1813
|
-
useOthersMapped: useOthersMappedSuspense,
|
|
1814
|
-
useOthersConnectionIds: useOthersConnectionIdsSuspense,
|
|
1815
|
-
useOther: useOtherSuspense,
|
|
1816
|
-
useMutation,
|
|
1817
|
-
useThreads: useThreadsSuspense,
|
|
1818
|
-
useCreateThread,
|
|
1819
|
-
useEditThreadMetadata,
|
|
1820
|
-
useCreateComment,
|
|
1821
|
-
useEditComment,
|
|
1822
|
-
useDeleteComment,
|
|
1823
|
-
useAddReaction,
|
|
1824
|
-
useRemoveReaction,
|
|
1825
|
-
useMarkThreadAsRead,
|
|
1826
|
-
useThreadSubscription,
|
|
1827
|
-
useRoomNotificationSettings: useRoomNotificationSettingsSuspense,
|
|
1828
|
-
useUpdateRoomNotificationSettings,
|
|
1829
|
-
...shared.suspense
|
|
1830
|
-
},
|
|
1831
|
-
[kInternal]: {
|
|
1832
|
-
useCurrentUserId,
|
|
1833
|
-
hasResolveMentionSuggestions: resolveMentionSuggestions !== void 0,
|
|
1834
|
-
useMentionSuggestions
|
|
1835
|
-
}
|
|
1836
|
-
};
|
|
1837
|
-
return Object.defineProperty(bundle, kInternal, {
|
|
1838
|
-
enumerable: false
|
|
1839
|
-
});
|
|
1840
|
-
}
|
|
1841
|
-
function getCurrentUserId(room) {
|
|
1842
|
-
const self = room.getSelf();
|
|
1843
|
-
if (self === null || self.id === void 0) {
|
|
1844
|
-
return "anonymous";
|
|
1845
|
-
} else {
|
|
1846
|
-
return self.id;
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
function handleApiError(err) {
|
|
1850
|
-
const message = `Request failed with status ${err.status}: ${err.message}`;
|
|
1851
|
-
if (err.details?.error === "FORBIDDEN") {
|
|
1852
|
-
const detailedMessage = [message, err.details.suggestion, err.details.docs].filter(Boolean).join("\n");
|
|
1853
|
-
console2.error(detailedMessage);
|
|
1854
|
-
}
|
|
1855
|
-
return new Error(message);
|
|
1856
|
-
}
|
|
1857
|
-
function generateQueryKey(roomId, options) {
|
|
1858
|
-
return `${roomId}-${stringify(options ?? {})}`;
|
|
1859
|
-
}
|
|
1860
|
-
|
|
1861
|
-
// src/shared.ts
|
|
1862
|
-
function useSharedContextBundle() {
|
|
1863
|
-
const roomContextBundle = useContext2(ContextBundle);
|
|
1864
|
-
const liveblocksContextBundle = useContext2(ContextBundle2);
|
|
1865
|
-
if (roomContextBundle !== null) {
|
|
1866
|
-
return roomContextBundle;
|
|
1867
|
-
} else if (liveblocksContextBundle !== null) {
|
|
1868
|
-
return liveblocksContextBundle;
|
|
1869
|
-
} else {
|
|
1870
|
-
throw new Error(
|
|
1871
|
-
"LiveblocksProvider or RoomProvider are missing from the React tree."
|
|
1872
|
-
);
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
var missingUserError = new Error(
|
|
1876
|
-
"resolveUsers didn't return anything for this user ID."
|
|
1877
|
-
);
|
|
1878
|
-
var missingRoomInfoError = new Error(
|
|
1879
|
-
"resolveRoomsInfo didn't return anything for this room ID."
|
|
1880
|
-
);
|
|
1881
|
-
function createSharedContext(client) {
|
|
1882
|
-
const usersStore = client[kInternal2].usersStore;
|
|
1883
|
-
const roomsInfoStore = client[kInternal2].roomsInfoStore;
|
|
1884
|
-
function useUser(userId) {
|
|
1885
|
-
const getUserState = useCallback2(
|
|
1886
|
-
() => usersStore.getState(userId),
|
|
1887
|
-
[userId]
|
|
1888
|
-
);
|
|
1889
|
-
useEffect4(() => {
|
|
1890
|
-
void usersStore.get(userId);
|
|
1891
|
-
}, [userId]);
|
|
1892
|
-
const state = useSyncExternalStore2(
|
|
1893
|
-
usersStore.subscribe,
|
|
1894
|
-
getUserState,
|
|
1895
|
-
getUserState
|
|
1896
|
-
);
|
|
1897
|
-
return state ? {
|
|
1898
|
-
isLoading: state.isLoading,
|
|
1899
|
-
user: state.data,
|
|
1900
|
-
// Return an error if `undefined` was returned by `resolveUsers` for this user ID
|
|
1901
|
-
error: !state.isLoading && !state.data && !state.error ? missingUserError : state.error
|
|
1902
|
-
} : { isLoading: true };
|
|
1903
|
-
}
|
|
1904
|
-
function useUserSuspense(userId) {
|
|
1905
|
-
const getUserState = useCallback2(
|
|
1906
|
-
() => usersStore.getState(userId),
|
|
1907
|
-
[userId]
|
|
1908
|
-
);
|
|
1909
|
-
const userState = getUserState();
|
|
1910
|
-
if (!userState || userState.isLoading) {
|
|
1911
|
-
throw usersStore.get(userId);
|
|
1912
|
-
}
|
|
1913
|
-
if (userState.error) {
|
|
1914
|
-
throw userState.error;
|
|
1915
|
-
}
|
|
1916
|
-
if (!userState.data) {
|
|
1917
|
-
throw missingUserError;
|
|
1918
|
-
}
|
|
1919
|
-
const state = useSyncExternalStore2(
|
|
1920
|
-
usersStore.subscribe,
|
|
1921
|
-
getUserState,
|
|
1922
|
-
getUserState
|
|
1923
|
-
);
|
|
1924
|
-
return {
|
|
1925
|
-
isLoading: false,
|
|
1926
|
-
user: state?.data,
|
|
1927
|
-
error: state?.error
|
|
1928
|
-
};
|
|
1929
|
-
}
|
|
1930
|
-
function useRoomInfo(roomId) {
|
|
1931
|
-
const getRoomInfoState = useCallback2(
|
|
1932
|
-
() => roomsInfoStore.getState(roomId),
|
|
1933
|
-
[roomId]
|
|
1934
|
-
);
|
|
1935
|
-
useEffect4(() => {
|
|
1936
|
-
void roomsInfoStore.get(roomId);
|
|
1937
|
-
}, [roomId]);
|
|
1938
|
-
const state = useSyncExternalStore2(
|
|
1939
|
-
roomsInfoStore.subscribe,
|
|
1940
|
-
getRoomInfoState,
|
|
1941
|
-
getRoomInfoState
|
|
1942
|
-
);
|
|
1943
|
-
return state ? {
|
|
1944
|
-
isLoading: state.isLoading,
|
|
1945
|
-
info: state.data,
|
|
1946
|
-
// Return an error if `undefined` was returned by `resolveRoomsInfo` for this room ID
|
|
1947
|
-
error: !state.isLoading && !state.data && !state.error ? missingRoomInfoError : state.error
|
|
1948
|
-
} : { isLoading: true };
|
|
1949
|
-
}
|
|
1950
|
-
function useRoomInfoSuspense(roomId) {
|
|
1951
|
-
const getRoomInfoState = useCallback2(
|
|
1952
|
-
() => roomsInfoStore.getState(roomId),
|
|
1953
|
-
[roomId]
|
|
1954
|
-
);
|
|
1955
|
-
const roomInfoState = getRoomInfoState();
|
|
1956
|
-
if (!roomInfoState || roomInfoState.isLoading) {
|
|
1957
|
-
throw roomsInfoStore.get(roomId);
|
|
1958
|
-
}
|
|
1959
|
-
if (roomInfoState.error) {
|
|
1960
|
-
throw roomInfoState.error;
|
|
1961
|
-
}
|
|
1962
|
-
if (!roomInfoState.data) {
|
|
1963
|
-
throw missingRoomInfoError;
|
|
1964
|
-
}
|
|
1965
|
-
const state = useSyncExternalStore2(
|
|
1966
|
-
roomsInfoStore.subscribe,
|
|
1967
|
-
getRoomInfoState,
|
|
1968
|
-
getRoomInfoState
|
|
1969
|
-
);
|
|
1970
|
-
return {
|
|
1971
|
-
isLoading: false,
|
|
1972
|
-
info: state?.data,
|
|
1973
|
-
error: state?.error
|
|
1974
|
-
};
|
|
1975
|
-
}
|
|
1976
|
-
const bundle = {
|
|
1977
|
-
useUser,
|
|
1978
|
-
useRoomInfo,
|
|
1979
|
-
suspense: {
|
|
1980
|
-
useUser: useUserSuspense,
|
|
1981
|
-
useRoomInfo: useRoomInfoSuspense
|
|
1982
|
-
}
|
|
1983
|
-
};
|
|
1984
|
-
return bundle;
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
// src/liveblocks.tsx
|
|
1988
|
-
var ContextBundle2 = createContext2(null);
|
|
1989
|
-
function useLiveblocksContextBundle() {
|
|
1990
|
-
const bundle = useContext3(ContextBundle2);
|
|
1991
|
-
if (bundle === null) {
|
|
1992
|
-
throw new Error("LiveblocksProvider is missing from the React tree.");
|
|
1993
|
-
}
|
|
1994
|
-
return bundle;
|
|
1995
|
-
}
|
|
1996
|
-
var POLLING_INTERVAL2 = 60 * 1e3;
|
|
1997
|
-
var INBOX_NOTIFICATIONS_QUERY = "INBOX_NOTIFICATIONS";
|
|
1998
|
-
function createLiveblocksContext(client) {
|
|
1999
|
-
const shared = createSharedContext(client);
|
|
2000
|
-
const store = client[kInternal3].cacheStore;
|
|
2001
|
-
const notifications = client[kInternal3].notifications;
|
|
2002
|
-
function LiveblocksProvider(props) {
|
|
2003
|
-
return /* @__PURE__ */ React3.createElement(
|
|
2004
|
-
ContextBundle2.Provider,
|
|
2005
|
-
{
|
|
2006
|
-
value: bundle
|
|
2007
|
-
},
|
|
2008
|
-
props.children
|
|
2009
|
-
);
|
|
2010
|
-
}
|
|
2011
|
-
let fetchInboxNotificationsRequest = null;
|
|
2012
|
-
let inboxNotificationsSubscribers = 0;
|
|
2013
|
-
let lastRequestedAt;
|
|
2014
|
-
const poller = makePoller2(refreshThreadsAndNotifications);
|
|
2015
|
-
function refreshThreadsAndNotifications() {
|
|
2016
|
-
return notifications.getInboxNotifications({ since: lastRequestedAt }).then(
|
|
2017
|
-
(result) => {
|
|
2018
|
-
lastRequestedAt = result.meta.requestedAt;
|
|
2019
|
-
store.updateThreadsAndNotifications(
|
|
2020
|
-
result.threads,
|
|
2021
|
-
result.inboxNotifications,
|
|
2022
|
-
result.deletedThreads,
|
|
2023
|
-
result.deletedInboxNotifications,
|
|
2024
|
-
INBOX_NOTIFICATIONS_QUERY
|
|
2025
|
-
);
|
|
2026
|
-
},
|
|
2027
|
-
() => {
|
|
2028
|
-
}
|
|
2029
|
-
);
|
|
2030
|
-
}
|
|
2031
|
-
function incrementInboxNotificationsSubscribers() {
|
|
2032
|
-
inboxNotificationsSubscribers++;
|
|
2033
|
-
poller.start(POLLING_INTERVAL2);
|
|
2034
|
-
}
|
|
2035
|
-
function decrementInboxNotificationsSubscribers() {
|
|
2036
|
-
if (inboxNotificationsSubscribers <= 0) {
|
|
2037
|
-
console.warn(
|
|
2038
|
-
`Internal unexpected behavior. Cannot decrease subscriber count for query "${INBOX_NOTIFICATIONS_QUERY}"`
|
|
2039
|
-
);
|
|
2040
|
-
return;
|
|
2041
|
-
}
|
|
2042
|
-
inboxNotificationsSubscribers--;
|
|
2043
|
-
if (inboxNotificationsSubscribers <= 0) {
|
|
2044
|
-
poller.stop();
|
|
2045
|
-
}
|
|
2046
|
-
}
|
|
2047
|
-
async function fetchInboxNotifications({ retryCount } = { retryCount: 0 }) {
|
|
2048
|
-
if (fetchInboxNotificationsRequest !== null) {
|
|
2049
|
-
return fetchInboxNotificationsRequest;
|
|
2050
|
-
}
|
|
2051
|
-
store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {
|
|
2052
|
-
isLoading: true
|
|
2053
|
-
});
|
|
2054
|
-
try {
|
|
2055
|
-
fetchInboxNotificationsRequest = notifications.getInboxNotifications();
|
|
2056
|
-
const result = await fetchInboxNotificationsRequest;
|
|
2057
|
-
store.updateThreadsAndNotifications(
|
|
2058
|
-
result.threads,
|
|
2059
|
-
result.inboxNotifications,
|
|
2060
|
-
result.deletedThreads,
|
|
2061
|
-
result.deletedInboxNotifications,
|
|
2062
|
-
INBOX_NOTIFICATIONS_QUERY
|
|
2063
|
-
);
|
|
2064
|
-
if (lastRequestedAt === void 0 || lastRequestedAt > result.meta.requestedAt) {
|
|
2065
|
-
lastRequestedAt = result.meta.requestedAt;
|
|
2066
|
-
}
|
|
2067
|
-
poller.start(POLLING_INTERVAL2);
|
|
2068
|
-
} catch (er) {
|
|
2069
|
-
fetchInboxNotificationsRequest = null;
|
|
2070
|
-
retryError(() => {
|
|
2071
|
-
void fetchInboxNotifications({
|
|
2072
|
-
retryCount: retryCount + 1
|
|
2073
|
-
});
|
|
2074
|
-
}, retryCount);
|
|
2075
|
-
store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {
|
|
2076
|
-
isLoading: false,
|
|
2077
|
-
error: er
|
|
2078
|
-
});
|
|
2079
|
-
}
|
|
2080
|
-
return;
|
|
2081
|
-
}
|
|
2082
|
-
function useInboxNotificationsSelectorCallback(state) {
|
|
2083
|
-
const query = state.queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2084
|
-
if (query === void 0 || query.isLoading) {
|
|
2085
|
-
return {
|
|
2086
|
-
isLoading: true
|
|
2087
|
-
};
|
|
2088
|
-
}
|
|
2089
|
-
if (query.error !== void 0) {
|
|
2090
|
-
return {
|
|
2091
|
-
error: query.error,
|
|
2092
|
-
isLoading: false
|
|
2093
|
-
};
|
|
2094
|
-
}
|
|
2095
|
-
return {
|
|
2096
|
-
inboxNotifications: selectedInboxNotifications(state),
|
|
2097
|
-
isLoading: false
|
|
2098
|
-
};
|
|
2099
|
-
}
|
|
2100
|
-
function useInboxNotifications() {
|
|
2101
|
-
useEffect5(() => {
|
|
2102
|
-
void fetchInboxNotifications();
|
|
2103
|
-
incrementInboxNotificationsSubscribers();
|
|
2104
|
-
return () => decrementInboxNotificationsSubscribers();
|
|
2105
|
-
}, []);
|
|
2106
|
-
const result = useSyncExternalStoreWithSelector2(
|
|
2107
|
-
store.subscribe,
|
|
2108
|
-
store.get,
|
|
2109
|
-
store.get,
|
|
2110
|
-
useInboxNotificationsSelectorCallback
|
|
2111
|
-
);
|
|
2112
|
-
return result;
|
|
2113
|
-
}
|
|
2114
|
-
function useInboxNotificationsSuspenseSelector(state) {
|
|
2115
|
-
return {
|
|
2116
|
-
inboxNotifications: selectedInboxNotifications(state),
|
|
2117
|
-
isLoading: false
|
|
2118
|
-
};
|
|
2119
|
-
}
|
|
2120
|
-
function useInboxNotificationsSuspense() {
|
|
2121
|
-
const query = store.get().queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2122
|
-
if (query === void 0 || query.isLoading) {
|
|
2123
|
-
throw fetchInboxNotifications();
|
|
2124
|
-
}
|
|
2125
|
-
if (query.error !== void 0) {
|
|
2126
|
-
throw query.error;
|
|
2127
|
-
}
|
|
2128
|
-
React3.useEffect(() => {
|
|
2129
|
-
incrementInboxNotificationsSubscribers();
|
|
2130
|
-
return () => {
|
|
2131
|
-
decrementInboxNotificationsSubscribers();
|
|
2132
|
-
};
|
|
2133
|
-
}, []);
|
|
2134
|
-
return useSyncExternalStoreWithSelector2(
|
|
2135
|
-
store.subscribe,
|
|
2136
|
-
store.get,
|
|
2137
|
-
store.get,
|
|
2138
|
-
useInboxNotificationsSuspenseSelector
|
|
2139
|
-
);
|
|
2140
|
-
}
|
|
2141
|
-
function selectUnreadInboxNotificationsCount(state) {
|
|
2142
|
-
let count = 0;
|
|
2143
|
-
for (const notification of selectedInboxNotifications(state)) {
|
|
2144
|
-
if (notification.readAt === null || notification.readAt < notification.notifiedAt) {
|
|
2145
|
-
count++;
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
return count;
|
|
2149
|
-
}
|
|
2150
|
-
function useUnreadInboxNotificationsCountSelector(state) {
|
|
2151
|
-
const query = state.queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2152
|
-
if (query === void 0 || query.isLoading) {
|
|
2153
|
-
return {
|
|
2154
|
-
isLoading: true
|
|
2155
|
-
};
|
|
2156
|
-
}
|
|
2157
|
-
if (query.error !== void 0) {
|
|
2158
|
-
return {
|
|
2159
|
-
error: query.error,
|
|
2160
|
-
isLoading: false
|
|
2161
|
-
};
|
|
2162
|
-
}
|
|
2163
|
-
return {
|
|
2164
|
-
isLoading: false,
|
|
2165
|
-
count: selectUnreadInboxNotificationsCount(state)
|
|
2166
|
-
};
|
|
2167
|
-
}
|
|
2168
|
-
function useUnreadInboxNotificationsCount() {
|
|
2169
|
-
useEffect5(() => {
|
|
2170
|
-
void fetchInboxNotifications();
|
|
2171
|
-
incrementInboxNotificationsSubscribers();
|
|
2172
|
-
return () => decrementInboxNotificationsSubscribers();
|
|
2173
|
-
}, []);
|
|
2174
|
-
return useSyncExternalStoreWithSelector2(
|
|
2175
|
-
store.subscribe,
|
|
2176
|
-
store.get,
|
|
2177
|
-
store.get,
|
|
2178
|
-
useUnreadInboxNotificationsCountSelector
|
|
2179
|
-
);
|
|
2180
|
-
}
|
|
2181
|
-
function useUnreadInboxNotificationsCountSuspenseSelector(state) {
|
|
2182
|
-
return {
|
|
2183
|
-
isLoading: false,
|
|
2184
|
-
count: selectUnreadInboxNotificationsCount(state)
|
|
2185
|
-
};
|
|
2186
|
-
}
|
|
2187
|
-
function useUnreadInboxNotificationsCountSuspense() {
|
|
2188
|
-
const query = store.get().queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2189
|
-
if (query === void 0 || query.isLoading) {
|
|
2190
|
-
throw fetchInboxNotifications();
|
|
2191
|
-
}
|
|
2192
|
-
React3.useEffect(() => {
|
|
2193
|
-
incrementInboxNotificationsSubscribers();
|
|
2194
|
-
return () => {
|
|
2195
|
-
decrementInboxNotificationsSubscribers();
|
|
2196
|
-
};
|
|
2197
|
-
}, []);
|
|
2198
|
-
return useSyncExternalStoreWithSelector2(
|
|
2199
|
-
store.subscribe,
|
|
2200
|
-
store.get,
|
|
2201
|
-
store.get,
|
|
2202
|
-
useUnreadInboxNotificationsCountSuspenseSelector
|
|
2203
|
-
);
|
|
2204
|
-
}
|
|
2205
|
-
function useMarkInboxNotificationAsRead() {
|
|
2206
|
-
return useCallback3((inboxNotificationId) => {
|
|
2207
|
-
const optimisticUpdateId = nanoid3();
|
|
2208
|
-
const readAt = /* @__PURE__ */ new Date();
|
|
2209
|
-
store.pushOptimisticUpdate({
|
|
2210
|
-
type: "mark-inbox-notification-as-read",
|
|
2211
|
-
id: optimisticUpdateId,
|
|
2212
|
-
inboxNotificationId,
|
|
2213
|
-
readAt
|
|
2214
|
-
});
|
|
2215
|
-
notifications.markInboxNotificationAsRead(inboxNotificationId).then(
|
|
2216
|
-
() => {
|
|
2217
|
-
store.set((state) => {
|
|
2218
|
-
const existingNotification = state.inboxNotifications[inboxNotificationId];
|
|
2219
|
-
if (existingNotification === void 0) {
|
|
2220
|
-
return {
|
|
2221
|
-
...state,
|
|
2222
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
2223
|
-
(update) => update.id !== optimisticUpdateId
|
|
2224
|
-
)
|
|
2225
|
-
};
|
|
2226
|
-
}
|
|
2227
|
-
return {
|
|
2228
|
-
...state,
|
|
2229
|
-
inboxNotifications: {
|
|
2230
|
-
...state.inboxNotifications,
|
|
2231
|
-
[inboxNotificationId]: {
|
|
2232
|
-
...existingNotification,
|
|
2233
|
-
readAt
|
|
2234
|
-
}
|
|
2235
|
-
},
|
|
2236
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
2237
|
-
(update) => update.id !== optimisticUpdateId
|
|
2238
|
-
)
|
|
2239
|
-
};
|
|
2240
|
-
});
|
|
2241
|
-
},
|
|
2242
|
-
() => {
|
|
2243
|
-
store.set((state) => ({
|
|
2244
|
-
...state,
|
|
2245
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
2246
|
-
(update) => update.id !== optimisticUpdateId
|
|
2247
|
-
)
|
|
2248
|
-
}));
|
|
2249
|
-
}
|
|
2250
|
-
);
|
|
2251
|
-
}, []);
|
|
2252
|
-
}
|
|
2253
|
-
function useMarkAllInboxNotificationsAsRead() {
|
|
2254
|
-
return useCallback3(() => {
|
|
2255
|
-
const optimisticUpdateId = nanoid3();
|
|
2256
|
-
const readAt = /* @__PURE__ */ new Date();
|
|
2257
|
-
store.pushOptimisticUpdate({
|
|
2258
|
-
type: "mark-inbox-notifications-as-read",
|
|
2259
|
-
id: optimisticUpdateId,
|
|
2260
|
-
readAt
|
|
2261
|
-
});
|
|
2262
|
-
notifications.markAllInboxNotificationsAsRead().then(
|
|
2263
|
-
() => {
|
|
2264
|
-
store.set((state) => ({
|
|
2265
|
-
...state,
|
|
2266
|
-
inboxNotifications: Object.fromEntries(
|
|
2267
|
-
Array.from(Object.entries(state.inboxNotifications)).map(
|
|
2268
|
-
([id, inboxNotification]) => [
|
|
2269
|
-
id,
|
|
2270
|
-
{ ...inboxNotification, readAt }
|
|
2271
|
-
]
|
|
2272
|
-
)
|
|
2273
|
-
),
|
|
2274
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
2275
|
-
(update) => update.id !== optimisticUpdateId
|
|
2276
|
-
)
|
|
2277
|
-
}));
|
|
2278
|
-
},
|
|
2279
|
-
() => {
|
|
2280
|
-
store.set((state) => ({
|
|
2281
|
-
...state,
|
|
2282
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
2283
|
-
(update) => update.id !== optimisticUpdateId
|
|
2284
|
-
)
|
|
2285
|
-
}));
|
|
2286
|
-
}
|
|
2287
|
-
);
|
|
2288
|
-
}, []);
|
|
2289
|
-
}
|
|
2290
|
-
function useInboxNotificationThread(inboxNotificationId) {
|
|
2291
|
-
const selector = useCallback3(
|
|
2292
|
-
(state) => {
|
|
2293
|
-
const inboxNotification = state.inboxNotifications[inboxNotificationId];
|
|
2294
|
-
if (inboxNotification === void 0) {
|
|
2295
|
-
throw new Error(
|
|
2296
|
-
`Inbox notification with ID "${inboxNotificationId}" not found`
|
|
2297
|
-
);
|
|
2298
|
-
}
|
|
2299
|
-
if (inboxNotification.kind !== "thread") {
|
|
2300
|
-
throw new Error(
|
|
2301
|
-
`Inbox notification with ID "${inboxNotificationId}" is not of kind "thread"`
|
|
2302
|
-
);
|
|
2303
|
-
}
|
|
2304
|
-
const thread = state.threads[inboxNotification.threadId];
|
|
2305
|
-
if (thread === void 0) {
|
|
2306
|
-
throw new Error(
|
|
2307
|
-
`Thread with ID "${inboxNotification.threadId}" not found, this inbox notification might not be of kind "thread"`
|
|
2308
|
-
);
|
|
2309
|
-
}
|
|
2310
|
-
return thread;
|
|
2311
|
-
},
|
|
2312
|
-
[inboxNotificationId]
|
|
2313
|
-
);
|
|
2314
|
-
return useSyncExternalStoreWithSelector2(
|
|
2315
|
-
store.subscribe,
|
|
2316
|
-
store.get,
|
|
2317
|
-
store.get,
|
|
2318
|
-
selector
|
|
2319
|
-
);
|
|
2320
|
-
}
|
|
2321
|
-
const currentUserIdStore = client[kInternal3].currentUserIdStore;
|
|
2322
|
-
function useCurrentUserId() {
|
|
2323
|
-
return useSyncExternalStore3(
|
|
2324
|
-
currentUserIdStore.subscribe,
|
|
2325
|
-
currentUserIdStore.get,
|
|
2326
|
-
currentUserIdStore.get
|
|
2327
|
-
);
|
|
2328
|
-
}
|
|
2329
|
-
const bundle = {
|
|
2330
|
-
LiveblocksProvider,
|
|
2331
|
-
useInboxNotifications,
|
|
2332
|
-
useUnreadInboxNotificationsCount,
|
|
2333
|
-
useMarkInboxNotificationAsRead,
|
|
2334
|
-
useMarkAllInboxNotificationsAsRead,
|
|
2335
|
-
useInboxNotificationThread,
|
|
2336
|
-
...shared,
|
|
2337
|
-
suspense: {
|
|
2338
|
-
LiveblocksProvider,
|
|
2339
|
-
useInboxNotifications: useInboxNotificationsSuspense,
|
|
2340
|
-
useUnreadInboxNotificationsCount: useUnreadInboxNotificationsCountSuspense,
|
|
2341
|
-
useMarkInboxNotificationAsRead,
|
|
2342
|
-
useMarkAllInboxNotificationsAsRead,
|
|
2343
|
-
useInboxNotificationThread,
|
|
2344
|
-
...shared.suspense
|
|
2345
|
-
},
|
|
2346
|
-
[kInternal3]: {
|
|
2347
|
-
useCurrentUserId
|
|
2348
|
-
}
|
|
2349
|
-
};
|
|
2350
|
-
return Object.defineProperty(bundle, kInternal3, {
|
|
2351
|
-
enumerable: false
|
|
2352
|
-
});
|
|
2353
|
-
}
|
|
2354
|
-
|
|
2355
|
-
// src/index.ts
|
|
2356
|
-
import { shallow as shallow2 } from "@liveblocks/client";
|
|
2357
60
|
detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
2358
61
|
export {
|
|
62
|
+
ClientContext,
|
|
2359
63
|
ClientSideSuspense,
|
|
64
|
+
LiveblocksProvider,
|
|
65
|
+
RoomContext,
|
|
66
|
+
_RoomProvider as RoomProvider,
|
|
2360
67
|
createLiveblocksContext,
|
|
2361
68
|
createRoomContext,
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
69
|
+
shallow,
|
|
70
|
+
_useAddReaction as useAddReaction,
|
|
71
|
+
useBatch,
|
|
72
|
+
_useBroadcastEvent as useBroadcastEvent,
|
|
73
|
+
useCanRedo,
|
|
74
|
+
useCanUndo,
|
|
75
|
+
useClient,
|
|
76
|
+
useCreateComment,
|
|
77
|
+
_useCreateThread as useCreateThread,
|
|
78
|
+
useDeleteComment,
|
|
79
|
+
useEditComment,
|
|
80
|
+
_useEditThreadMetadata as useEditThreadMetadata,
|
|
81
|
+
useErrorListener,
|
|
82
|
+
_useEventListener as useEventListener,
|
|
83
|
+
useHistory,
|
|
84
|
+
__1 as useInboxNotificationThread,
|
|
85
|
+
useInboxNotifications,
|
|
86
|
+
useLostConnectionListener,
|
|
87
|
+
useMarkAllInboxNotificationsAsRead,
|
|
88
|
+
useMarkInboxNotificationAsRead,
|
|
89
|
+
useMarkThreadAsRead,
|
|
90
|
+
_useMutation as useMutation,
|
|
91
|
+
_useMyPresence as useMyPresence,
|
|
92
|
+
_useOther as useOther,
|
|
93
|
+
_useOthers as useOthers,
|
|
94
|
+
useOthersConnectionIds,
|
|
95
|
+
_useOthersListener as useOthersListener,
|
|
96
|
+
_useOthersMapped as useOthersMapped,
|
|
97
|
+
useRedo,
|
|
98
|
+
useRemoveReaction,
|
|
99
|
+
_useRoom as useRoom,
|
|
100
|
+
useRoomInfo,
|
|
101
|
+
useRoomNotificationSettings,
|
|
102
|
+
_useSelf as useSelf,
|
|
103
|
+
useStatus,
|
|
104
|
+
_useStorage as useStorage,
|
|
105
|
+
_useStorageRoot as useStorageRoot,
|
|
106
|
+
useThreadSubscription,
|
|
107
|
+
_useThreads as useThreads,
|
|
108
|
+
useUndo,
|
|
109
|
+
useUnreadInboxNotificationsCount,
|
|
110
|
+
_useUpdateMyPresence as useUpdateMyPresence,
|
|
111
|
+
useUpdateRoomNotificationSettings,
|
|
112
|
+
__2 as useUser
|
|
2366
113
|
};
|
|
2367
114
|
//# sourceMappingURL=index.mjs.map
|