@liveblocks/core 1.10.0-beta3 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +34 -68
- package/dist/index.d.ts +34 -68
- package/dist/index.js +326 -177
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +301 -152
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "1.10.0
|
|
9
|
+
var PKG_VERSION = "1.10.0";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -362,23 +362,29 @@ var FSM = class {
|
|
|
362
362
|
}
|
|
363
363
|
onEnterAsync(nameOrPattern, promiseFn, onOK, onError) {
|
|
364
364
|
return this.onEnter(nameOrPattern, () => {
|
|
365
|
-
|
|
366
|
-
|
|
365
|
+
const abortController = new AbortController();
|
|
366
|
+
const signal = abortController.signal;
|
|
367
|
+
let done = false;
|
|
368
|
+
void promiseFn(this.currentContext.current, signal).then(
|
|
367
369
|
// On OK
|
|
368
370
|
(data) => {
|
|
369
|
-
if (!
|
|
371
|
+
if (!signal.aborted) {
|
|
372
|
+
done = true;
|
|
370
373
|
this.transition({ type: "ASYNC_OK", data }, onOK);
|
|
371
374
|
}
|
|
372
375
|
},
|
|
373
376
|
// On Error
|
|
374
377
|
(reason) => {
|
|
375
|
-
if (!
|
|
378
|
+
if (!signal.aborted) {
|
|
379
|
+
done = true;
|
|
376
380
|
this.transition({ type: "ASYNC_ERROR", reason }, onError);
|
|
377
381
|
}
|
|
378
382
|
}
|
|
379
383
|
);
|
|
380
384
|
return () => {
|
|
381
|
-
|
|
385
|
+
if (!done) {
|
|
386
|
+
abortController.abort();
|
|
387
|
+
}
|
|
382
388
|
};
|
|
383
389
|
});
|
|
384
390
|
}
|
|
@@ -652,6 +658,7 @@ var ServerMsgCode = /* @__PURE__ */ ((ServerMsgCode2) => {
|
|
|
652
658
|
|
|
653
659
|
// src/types/IWebSocket.ts
|
|
654
660
|
var WebsocketCloseCodes = /* @__PURE__ */ ((WebsocketCloseCodes2) => {
|
|
661
|
+
WebsocketCloseCodes2[WebsocketCloseCodes2["CLOSE_NORMAL"] = 1e3] = "CLOSE_NORMAL";
|
|
655
662
|
WebsocketCloseCodes2[WebsocketCloseCodes2["CLOSE_ABNORMAL"] = 1006] = "CLOSE_ABNORMAL";
|
|
656
663
|
WebsocketCloseCodes2[WebsocketCloseCodes2["UNEXPECTED_CONDITION"] = 1011] = "UNEXPECTED_CONDITION";
|
|
657
664
|
WebsocketCloseCodes2[WebsocketCloseCodes2["TRY_AGAIN_LATER"] = 1013] = "TRY_AGAIN_LATER";
|
|
@@ -661,6 +668,7 @@ var WebsocketCloseCodes = /* @__PURE__ */ ((WebsocketCloseCodes2) => {
|
|
|
661
668
|
WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS"] = 4003] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS";
|
|
662
669
|
WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP"] = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP";
|
|
663
670
|
WebsocketCloseCodes2[WebsocketCloseCodes2["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM"] = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM";
|
|
671
|
+
WebsocketCloseCodes2[WebsocketCloseCodes2["KICKED"] = 4100] = "KICKED";
|
|
664
672
|
WebsocketCloseCodes2[WebsocketCloseCodes2["TOKEN_EXPIRED"] = 4109] = "TOKEN_EXPIRED";
|
|
665
673
|
WebsocketCloseCodes2[WebsocketCloseCodes2["CLOSE_WITHOUT_RETRY"] = 4999] = "CLOSE_WITHOUT_RETRY";
|
|
666
674
|
return WebsocketCloseCodes2;
|
|
@@ -728,6 +736,7 @@ var StopRetrying = class extends Error {
|
|
|
728
736
|
}
|
|
729
737
|
};
|
|
730
738
|
var LiveblocksError = class extends Error {
|
|
739
|
+
/** @internal */
|
|
731
740
|
constructor(message, code) {
|
|
732
741
|
super(message);
|
|
733
742
|
this.code = code;
|
|
@@ -942,14 +951,16 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
942
951
|
// When the "open" event happens, we're ready to transition to the
|
|
943
952
|
// OK state. This is done by resolving the Promise.
|
|
944
953
|
//
|
|
945
|
-
async (ctx) => {
|
|
954
|
+
async (ctx, signal) => {
|
|
946
955
|
let capturedPrematureEvent = null;
|
|
956
|
+
let unconfirmedSocket = null;
|
|
947
957
|
const connect$ = new Promise(
|
|
948
958
|
(resolve, rej) => {
|
|
949
959
|
if (ctx.authValue === null) {
|
|
950
960
|
throw new Error("No auth authValue");
|
|
951
961
|
}
|
|
952
962
|
const socket = delegates.createSocket(ctx.authValue);
|
|
963
|
+
unconfirmedSocket = socket;
|
|
953
964
|
function reject(event) {
|
|
954
965
|
capturedPrematureEvent = event;
|
|
955
966
|
socket.removeEventListener("message", onSocketMessage);
|
|
@@ -1005,12 +1016,18 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
1005
1016
|
//
|
|
1006
1017
|
([socket, unsub]) => {
|
|
1007
1018
|
unsub();
|
|
1019
|
+
if (signal.aborted) {
|
|
1020
|
+
throw new Error("Aborted");
|
|
1021
|
+
}
|
|
1008
1022
|
if (capturedPrematureEvent) {
|
|
1009
1023
|
throw capturedPrematureEvent;
|
|
1010
1024
|
}
|
|
1011
1025
|
return socket;
|
|
1012
1026
|
}
|
|
1013
|
-
)
|
|
1027
|
+
).catch((e) => {
|
|
1028
|
+
teardownSocket(unconfirmedSocket);
|
|
1029
|
+
throw e;
|
|
1030
|
+
});
|
|
1014
1031
|
},
|
|
1015
1032
|
// Only transition to OK state after a successfully opened WebSocket connection
|
|
1016
1033
|
(okEvent) => ({
|
|
@@ -1338,6 +1355,9 @@ function createAuthManager(authOptions) {
|
|
|
1338
1355
|
if (token.parsed.k === "id" /* ID_TOKEN */) {
|
|
1339
1356
|
return token;
|
|
1340
1357
|
} else if (token.parsed.k === "acc" /* ACCESS_TOKEN */) {
|
|
1358
|
+
if (!requestOptions.roomId && Object.entries(token.parsed.perms).length === 0) {
|
|
1359
|
+
return token;
|
|
1360
|
+
}
|
|
1341
1361
|
for (const [resource, scopes] of Object.entries(token.parsed.perms)) {
|
|
1342
1362
|
if (!requestOptions.roomId) {
|
|
1343
1363
|
if (resource.includes("*") && hasCorrespondingScopes(requestOptions.requestedScope, scopes)) {
|
|
@@ -1397,6 +1417,9 @@ function createAuthManager(authOptions) {
|
|
|
1397
1417
|
}
|
|
1398
1418
|
function verifyTokenPermissions(parsedToken, options) {
|
|
1399
1419
|
if (!options.roomId && parsedToken.parsed.k === "acc" /* ACCESS_TOKEN */) {
|
|
1420
|
+
if (Object.entries(parsedToken.parsed.perms).length === 0) {
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1400
1423
|
for (const [resource, scopes] of Object.entries(
|
|
1401
1424
|
parsedToken.parsed.perms
|
|
1402
1425
|
)) {
|
|
@@ -1405,7 +1428,7 @@ function createAuthManager(authOptions) {
|
|
|
1405
1428
|
}
|
|
1406
1429
|
}
|
|
1407
1430
|
throw new StopRetrying(
|
|
1408
|
-
"The issued
|
|
1431
|
+
"The issued access token doesn't grant enough permissions. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/access-tokens-not-enough-permissions"
|
|
1409
1432
|
);
|
|
1410
1433
|
}
|
|
1411
1434
|
}
|
|
@@ -2049,7 +2072,7 @@ function urljoin(baseUrl, path, params) {
|
|
|
2049
2072
|
|
|
2050
2073
|
// src/notifications.ts
|
|
2051
2074
|
var MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY = 50;
|
|
2052
|
-
function
|
|
2075
|
+
function createNotificationsApi({
|
|
2053
2076
|
baseUrl,
|
|
2054
2077
|
authManager,
|
|
2055
2078
|
currentUserIdStore,
|
|
@@ -5187,7 +5210,7 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5187
5210
|
);
|
|
5188
5211
|
return convertToCommentData(comment);
|
|
5189
5212
|
}
|
|
5190
|
-
async function
|
|
5213
|
+
async function deleteComment2({
|
|
5191
5214
|
threadId,
|
|
5192
5215
|
commentId
|
|
5193
5216
|
}) {
|
|
@@ -5200,7 +5223,7 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5200
5223
|
}
|
|
5201
5224
|
);
|
|
5202
5225
|
}
|
|
5203
|
-
async function
|
|
5226
|
+
async function addReaction2({
|
|
5204
5227
|
threadId,
|
|
5205
5228
|
commentId,
|
|
5206
5229
|
emoji
|
|
@@ -5219,7 +5242,7 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5219
5242
|
);
|
|
5220
5243
|
return convertToCommentUserReaction(reaction);
|
|
5221
5244
|
}
|
|
5222
|
-
async function
|
|
5245
|
+
async function removeReaction2({
|
|
5223
5246
|
threadId,
|
|
5224
5247
|
commentId,
|
|
5225
5248
|
emoji
|
|
@@ -5240,11 +5263,12 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5240
5263
|
editThreadMetadata,
|
|
5241
5264
|
createComment,
|
|
5242
5265
|
editComment,
|
|
5243
|
-
deleteComment,
|
|
5244
|
-
addReaction,
|
|
5245
|
-
removeReaction
|
|
5266
|
+
deleteComment: deleteComment2,
|
|
5267
|
+
addReaction: addReaction2,
|
|
5268
|
+
removeReaction: removeReaction2
|
|
5246
5269
|
};
|
|
5247
5270
|
}
|
|
5271
|
+
var MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY2 = 50;
|
|
5248
5272
|
function createRoom(options, config) {
|
|
5249
5273
|
const initialPresence = typeof options.initialPresence === "function" ? options.initialPresence(config.roomId) : options.initialPresence;
|
|
5250
5274
|
const initialStorage = typeof options.initialStorage === "function" ? options.initialStorage(config.roomId) : options.initialStorage;
|
|
@@ -5292,9 +5316,6 @@ function createRoom(options, config) {
|
|
|
5292
5316
|
opClock: 0,
|
|
5293
5317
|
nodes: /* @__PURE__ */ new Map(),
|
|
5294
5318
|
root: void 0,
|
|
5295
|
-
comments: {
|
|
5296
|
-
lastRequestedAt: null
|
|
5297
|
-
},
|
|
5298
5319
|
undoStack: [],
|
|
5299
5320
|
redoStack: [],
|
|
5300
5321
|
pausedHistory: null,
|
|
@@ -6299,7 +6320,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6299
6320
|
delegates.authenticate,
|
|
6300
6321
|
fetchClientApi
|
|
6301
6322
|
);
|
|
6302
|
-
async function
|
|
6323
|
+
async function fetchNotificationsJson(endpoint, options2) {
|
|
6303
6324
|
const authValue = await delegates.authenticate();
|
|
6304
6325
|
const response = await fetchClientApi(
|
|
6305
6326
|
config.roomId,
|
|
@@ -6309,16 +6330,21 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6309
6330
|
);
|
|
6310
6331
|
if (!response.ok) {
|
|
6311
6332
|
if (response.status >= 400 && response.status < 600) {
|
|
6312
|
-
let
|
|
6333
|
+
let error3;
|
|
6313
6334
|
try {
|
|
6314
6335
|
const errorBody = await response.json();
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6336
|
+
error3 = new NotificationsApiError(
|
|
6337
|
+
errorBody.message,
|
|
6338
|
+
response.status,
|
|
6339
|
+
errorBody
|
|
6340
|
+
);
|
|
6341
|
+
} catch {
|
|
6342
|
+
error3 = new NotificationsApiError(
|
|
6343
|
+
response.statusText,
|
|
6344
|
+
response.status
|
|
6345
|
+
);
|
|
6318
6346
|
}
|
|
6319
|
-
throw
|
|
6320
|
-
`Request failed with status ${response.status}: ${errorMessage}`
|
|
6321
|
-
);
|
|
6347
|
+
throw error3;
|
|
6322
6348
|
}
|
|
6323
6349
|
}
|
|
6324
6350
|
let body;
|
|
@@ -6330,20 +6356,44 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6330
6356
|
return body;
|
|
6331
6357
|
}
|
|
6332
6358
|
function getRoomNotificationSettings() {
|
|
6333
|
-
return
|
|
6359
|
+
return fetchNotificationsJson(
|
|
6360
|
+
"/notification-settings"
|
|
6361
|
+
);
|
|
6334
6362
|
}
|
|
6335
6363
|
function updateRoomNotificationSettings(settings) {
|
|
6336
|
-
return
|
|
6364
|
+
return fetchNotificationsJson(
|
|
6365
|
+
"/notification-settings",
|
|
6366
|
+
{
|
|
6367
|
+
method: "POST",
|
|
6368
|
+
body: JSON.stringify(settings),
|
|
6369
|
+
headers: {
|
|
6370
|
+
"Content-Type": "application/json"
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6373
|
+
);
|
|
6374
|
+
}
|
|
6375
|
+
async function markInboxNotificationsAsRead(inboxNotificationIds) {
|
|
6376
|
+
await fetchNotificationsJson("/inbox-notifications/read", {
|
|
6337
6377
|
method: "POST",
|
|
6338
|
-
body: JSON.stringify(settings),
|
|
6339
6378
|
headers: {
|
|
6340
6379
|
"Content-Type": "application/json"
|
|
6341
|
-
}
|
|
6380
|
+
},
|
|
6381
|
+
body: JSON.stringify({ inboxNotificationIds })
|
|
6342
6382
|
});
|
|
6343
6383
|
}
|
|
6384
|
+
const batchedMarkInboxNotificationsAsRead = new Batch(
|
|
6385
|
+
async (batchedInboxNotificationIds) => {
|
|
6386
|
+
const inboxNotificationIds = batchedInboxNotificationIds.flat();
|
|
6387
|
+
await markInboxNotificationsAsRead(inboxNotificationIds);
|
|
6388
|
+
return inboxNotificationIds;
|
|
6389
|
+
},
|
|
6390
|
+
{ delay: MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY2 }
|
|
6391
|
+
);
|
|
6392
|
+
async function markInboxNotificationAsRead(inboxNotificationId) {
|
|
6393
|
+
await batchedMarkInboxNotificationsAsRead.get(inboxNotificationId);
|
|
6394
|
+
}
|
|
6344
6395
|
return Object.defineProperty(
|
|
6345
6396
|
{
|
|
6346
|
-
/* NOTE: Exposing internals here only to allow testing implementation details in unit tests */
|
|
6347
6397
|
[kInternal]: {
|
|
6348
6398
|
get presenceBuffer() {
|
|
6349
6399
|
return deepClone(context.buffer.presenceUpdates?.data ?? null);
|
|
@@ -6367,12 +6417,12 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6367
6417
|
rawSend: (data) => managedSocket.send(data)
|
|
6368
6418
|
},
|
|
6369
6419
|
comments: {
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6420
|
+
...commentsApi
|
|
6421
|
+
},
|
|
6422
|
+
notifications: {
|
|
6423
|
+
getRoomNotificationSettings,
|
|
6424
|
+
updateRoomNotificationSettings,
|
|
6425
|
+
markInboxNotificationAsRead
|
|
6376
6426
|
}
|
|
6377
6427
|
},
|
|
6378
6428
|
id: config.roomId,
|
|
@@ -6410,12 +6460,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6410
6460
|
getSelf: () => self.current,
|
|
6411
6461
|
// Presence
|
|
6412
6462
|
getPresence: () => context.myPresence.current,
|
|
6413
|
-
getOthers: () => context.others.current
|
|
6414
|
-
// Comments
|
|
6415
|
-
...commentsApi,
|
|
6416
|
-
// Notifications
|
|
6417
|
-
getRoomNotificationSettings,
|
|
6418
|
-
updateRoomNotificationSettings
|
|
6463
|
+
getOthers: () => context.others.current
|
|
6419
6464
|
},
|
|
6420
6465
|
// Explictly make the internal field non-enumerable, to avoid aggressive
|
|
6421
6466
|
// freezing when used with Immer
|
|
@@ -6680,8 +6725,15 @@ function applyOptimisticUpdates(state) {
|
|
|
6680
6725
|
if (thread === void 0) {
|
|
6681
6726
|
break;
|
|
6682
6727
|
}
|
|
6728
|
+
if (thread.deletedAt !== void 0) {
|
|
6729
|
+
break;
|
|
6730
|
+
}
|
|
6731
|
+
if (thread.updatedAt !== void 0 && thread.updatedAt > optimisticUpdate.updatedAt) {
|
|
6732
|
+
break;
|
|
6733
|
+
}
|
|
6683
6734
|
result.threads[thread.id] = {
|
|
6684
6735
|
...thread,
|
|
6736
|
+
updatedAt: optimisticUpdate.updatedAt,
|
|
6685
6737
|
metadata: {
|
|
6686
6738
|
...thread.metadata,
|
|
6687
6739
|
...optimisticUpdate.metadata
|
|
@@ -6694,16 +6746,17 @@ function applyOptimisticUpdates(state) {
|
|
|
6694
6746
|
if (thread === void 0) {
|
|
6695
6747
|
break;
|
|
6696
6748
|
}
|
|
6697
|
-
result.threads[thread.id] =
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6749
|
+
result.threads[thread.id] = upsertComment(
|
|
6750
|
+
thread,
|
|
6751
|
+
optimisticUpdate.comment
|
|
6752
|
+
);
|
|
6753
|
+
const inboxNotification = Object.values(result.inboxNotifications).find(
|
|
6754
|
+
(notification) => notification.threadId === thread.id
|
|
6755
|
+
);
|
|
6756
|
+
if (inboxNotification === void 0) {
|
|
6703
6757
|
break;
|
|
6704
6758
|
}
|
|
6705
|
-
|
|
6706
|
-
result.inboxNotifications[optimisticUpdate.inboxNotificationId] = {
|
|
6759
|
+
result.inboxNotifications[inboxNotification.id] = {
|
|
6707
6760
|
...inboxNotification,
|
|
6708
6761
|
notifiedAt: optimisticUpdate.comment.createdAt,
|
|
6709
6762
|
readAt: optimisticUpdate.comment.createdAt
|
|
@@ -6711,20 +6764,14 @@ function applyOptimisticUpdates(state) {
|
|
|
6711
6764
|
break;
|
|
6712
6765
|
}
|
|
6713
6766
|
case "edit-comment": {
|
|
6714
|
-
const thread = result.threads[optimisticUpdate.threadId];
|
|
6767
|
+
const thread = result.threads[optimisticUpdate.comment.threadId];
|
|
6715
6768
|
if (thread === void 0) {
|
|
6716
6769
|
break;
|
|
6717
6770
|
}
|
|
6718
|
-
result.threads[thread.id] =
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
...comment,
|
|
6723
|
-
editedAt: optimisticUpdate.editedAt,
|
|
6724
|
-
body: optimisticUpdate.body
|
|
6725
|
-
} : comment
|
|
6726
|
-
)
|
|
6727
|
-
};
|
|
6771
|
+
result.threads[thread.id] = upsertComment(
|
|
6772
|
+
thread,
|
|
6773
|
+
optimisticUpdate.comment
|
|
6774
|
+
);
|
|
6728
6775
|
break;
|
|
6729
6776
|
}
|
|
6730
6777
|
case "delete-comment": {
|
|
@@ -6732,21 +6779,11 @@ function applyOptimisticUpdates(state) {
|
|
|
6732
6779
|
if (thread === void 0) {
|
|
6733
6780
|
break;
|
|
6734
6781
|
}
|
|
6735
|
-
result.threads[thread.id] =
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
deletedAt: optimisticUpdate.deletedAt,
|
|
6741
|
-
body: void 0
|
|
6742
|
-
} : comment
|
|
6743
|
-
)
|
|
6744
|
-
};
|
|
6745
|
-
if (!result.threads[thread.id].comments.some(
|
|
6746
|
-
(comment) => comment.deletedAt === void 0
|
|
6747
|
-
)) {
|
|
6748
|
-
delete result.threads[thread.id];
|
|
6749
|
-
}
|
|
6782
|
+
result.threads[thread.id] = deleteComment(
|
|
6783
|
+
thread,
|
|
6784
|
+
optimisticUpdate.commentId,
|
|
6785
|
+
optimisticUpdate.deletedAt
|
|
6786
|
+
);
|
|
6750
6787
|
break;
|
|
6751
6788
|
}
|
|
6752
6789
|
case "add-reaction": {
|
|
@@ -6754,43 +6791,11 @@ function applyOptimisticUpdates(state) {
|
|
|
6754
6791
|
if (thread === void 0) {
|
|
6755
6792
|
break;
|
|
6756
6793
|
}
|
|
6757
|
-
result.threads[thread.id] =
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
(reaction) => reaction.emoji === optimisticUpdate.emoji
|
|
6763
|
-
)) {
|
|
6764
|
-
return {
|
|
6765
|
-
...comment,
|
|
6766
|
-
reactions: comment.reactions.map(
|
|
6767
|
-
(reaction) => reaction.emoji === optimisticUpdate.emoji ? {
|
|
6768
|
-
...reaction,
|
|
6769
|
-
users: [
|
|
6770
|
-
...reaction.users,
|
|
6771
|
-
{ id: optimisticUpdate.userId }
|
|
6772
|
-
]
|
|
6773
|
-
} : reaction
|
|
6774
|
-
)
|
|
6775
|
-
};
|
|
6776
|
-
} else {
|
|
6777
|
-
return {
|
|
6778
|
-
...comment,
|
|
6779
|
-
reactions: [
|
|
6780
|
-
...comment.reactions,
|
|
6781
|
-
{
|
|
6782
|
-
emoji: optimisticUpdate.emoji,
|
|
6783
|
-
createdAt: optimisticUpdate.createdAt,
|
|
6784
|
-
users: [{ id: optimisticUpdate.userId }]
|
|
6785
|
-
}
|
|
6786
|
-
]
|
|
6787
|
-
};
|
|
6788
|
-
}
|
|
6789
|
-
} else {
|
|
6790
|
-
return comment;
|
|
6791
|
-
}
|
|
6792
|
-
})
|
|
6793
|
-
};
|
|
6794
|
+
result.threads[thread.id] = addReaction(
|
|
6795
|
+
thread,
|
|
6796
|
+
optimisticUpdate.commentId,
|
|
6797
|
+
optimisticUpdate.reaction
|
|
6798
|
+
);
|
|
6794
6799
|
break;
|
|
6795
6800
|
}
|
|
6796
6801
|
case "remove-reaction": {
|
|
@@ -6798,37 +6803,13 @@ function applyOptimisticUpdates(state) {
|
|
|
6798
6803
|
if (thread === void 0) {
|
|
6799
6804
|
break;
|
|
6800
6805
|
}
|
|
6801
|
-
result.threads[thread.id] =
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
(reaction) => reaction.emoji === optimisticUpdate.emoji
|
|
6809
|
-
);
|
|
6810
|
-
let reactions = comment.reactions;
|
|
6811
|
-
if (reactionIndex >= 0 && comment.reactions[reactionIndex].users.some(
|
|
6812
|
-
(user) => user.id === optimisticUpdate.userId
|
|
6813
|
-
)) {
|
|
6814
|
-
if (comment.reactions[reactionIndex].users.length <= 1) {
|
|
6815
|
-
reactions = [...comment.reactions];
|
|
6816
|
-
reactions.splice(reactionIndex, 1);
|
|
6817
|
-
} else {
|
|
6818
|
-
reactions[reactionIndex] = {
|
|
6819
|
-
...reactions[reactionIndex],
|
|
6820
|
-
users: reactions[reactionIndex].users.filter(
|
|
6821
|
-
(user) => user.id !== optimisticUpdate.userId
|
|
6822
|
-
)
|
|
6823
|
-
};
|
|
6824
|
-
}
|
|
6825
|
-
}
|
|
6826
|
-
return {
|
|
6827
|
-
...comment,
|
|
6828
|
-
reactions
|
|
6829
|
-
};
|
|
6830
|
-
})
|
|
6831
|
-
};
|
|
6806
|
+
result.threads[thread.id] = removeReaction(
|
|
6807
|
+
thread,
|
|
6808
|
+
optimisticUpdate.commentId,
|
|
6809
|
+
optimisticUpdate.emoji,
|
|
6810
|
+
optimisticUpdate.userId,
|
|
6811
|
+
optimisticUpdate.removedAt
|
|
6812
|
+
);
|
|
6832
6813
|
break;
|
|
6833
6814
|
}
|
|
6834
6815
|
case "mark-inbox-notification-as-read": {
|
|
@@ -6910,6 +6891,169 @@ function compareInboxNotifications(inboxNotificationA, inboxNotificationB) {
|
|
|
6910
6891
|
}
|
|
6911
6892
|
return 0;
|
|
6912
6893
|
}
|
|
6894
|
+
function upsertComment(thread, comment) {
|
|
6895
|
+
if (thread.deletedAt !== void 0) {
|
|
6896
|
+
return thread;
|
|
6897
|
+
}
|
|
6898
|
+
if (comment.threadId !== thread.id) {
|
|
6899
|
+
warn(
|
|
6900
|
+
`Comment ${comment.id} does not belong to thread ${thread.id}`
|
|
6901
|
+
);
|
|
6902
|
+
return thread;
|
|
6903
|
+
}
|
|
6904
|
+
const existingComment = thread.comments.find(
|
|
6905
|
+
(existingComment2) => existingComment2.id === comment.id
|
|
6906
|
+
);
|
|
6907
|
+
if (existingComment === void 0) {
|
|
6908
|
+
const updatedAt = new Date(
|
|
6909
|
+
Math.max(thread.updatedAt?.getTime() || 0, comment.createdAt.getTime())
|
|
6910
|
+
);
|
|
6911
|
+
const updatedThread = {
|
|
6912
|
+
...thread,
|
|
6913
|
+
updatedAt,
|
|
6914
|
+
comments: [...thread.comments, comment]
|
|
6915
|
+
};
|
|
6916
|
+
return updatedThread;
|
|
6917
|
+
}
|
|
6918
|
+
if (existingComment.deletedAt !== void 0) {
|
|
6919
|
+
return thread;
|
|
6920
|
+
}
|
|
6921
|
+
if (existingComment.editedAt === void 0 || comment.editedAt === void 0 || existingComment.editedAt <= comment.editedAt) {
|
|
6922
|
+
const updatedComments = thread.comments.map(
|
|
6923
|
+
(existingComment2) => existingComment2.id === comment.id ? comment : existingComment2
|
|
6924
|
+
);
|
|
6925
|
+
const updatedThread = {
|
|
6926
|
+
...thread,
|
|
6927
|
+
updatedAt: new Date(
|
|
6928
|
+
Math.max(
|
|
6929
|
+
thread.updatedAt?.getTime() || 0,
|
|
6930
|
+
comment.editedAt?.getTime() || comment.createdAt.getTime()
|
|
6931
|
+
)
|
|
6932
|
+
),
|
|
6933
|
+
comments: updatedComments
|
|
6934
|
+
};
|
|
6935
|
+
return updatedThread;
|
|
6936
|
+
}
|
|
6937
|
+
return thread;
|
|
6938
|
+
}
|
|
6939
|
+
function deleteComment(thread, commentId, deletedAt) {
|
|
6940
|
+
if (thread.deletedAt !== void 0) {
|
|
6941
|
+
return thread;
|
|
6942
|
+
}
|
|
6943
|
+
const existingComment = thread.comments.find(
|
|
6944
|
+
(comment) => comment.id === commentId
|
|
6945
|
+
);
|
|
6946
|
+
if (existingComment === void 0) {
|
|
6947
|
+
return thread;
|
|
6948
|
+
}
|
|
6949
|
+
if (existingComment.deletedAt !== void 0) {
|
|
6950
|
+
return thread;
|
|
6951
|
+
}
|
|
6952
|
+
const updatedComments = thread.comments.map(
|
|
6953
|
+
(comment) => comment.id === commentId ? {
|
|
6954
|
+
...comment,
|
|
6955
|
+
deletedAt,
|
|
6956
|
+
body: void 0
|
|
6957
|
+
} : comment
|
|
6958
|
+
);
|
|
6959
|
+
if (!updatedComments.some((comment) => comment.deletedAt === void 0)) {
|
|
6960
|
+
return {
|
|
6961
|
+
...thread,
|
|
6962
|
+
deletedAt,
|
|
6963
|
+
updatedAt: deletedAt,
|
|
6964
|
+
comments: []
|
|
6965
|
+
};
|
|
6966
|
+
}
|
|
6967
|
+
return {
|
|
6968
|
+
...thread,
|
|
6969
|
+
updatedAt: deletedAt,
|
|
6970
|
+
comments: updatedComments
|
|
6971
|
+
};
|
|
6972
|
+
}
|
|
6973
|
+
function addReaction(thread, commentId, reaction) {
|
|
6974
|
+
if (thread.deletedAt !== void 0) {
|
|
6975
|
+
return thread;
|
|
6976
|
+
}
|
|
6977
|
+
const existingComment = thread.comments.find(
|
|
6978
|
+
(comment) => comment.id === commentId
|
|
6979
|
+
);
|
|
6980
|
+
if (existingComment === void 0) {
|
|
6981
|
+
return thread;
|
|
6982
|
+
}
|
|
6983
|
+
if (existingComment.deletedAt !== void 0) {
|
|
6984
|
+
return thread;
|
|
6985
|
+
}
|
|
6986
|
+
const updatedComments = thread.comments.map(
|
|
6987
|
+
(comment) => comment.id === commentId ? {
|
|
6988
|
+
...comment,
|
|
6989
|
+
reactions: upsertReaction(comment.reactions, reaction)
|
|
6990
|
+
} : comment
|
|
6991
|
+
);
|
|
6992
|
+
return {
|
|
6993
|
+
...thread,
|
|
6994
|
+
updatedAt: new Date(
|
|
6995
|
+
Math.max(reaction.createdAt.getTime(), thread.updatedAt?.getTime() || 0)
|
|
6996
|
+
),
|
|
6997
|
+
comments: updatedComments
|
|
6998
|
+
};
|
|
6999
|
+
}
|
|
7000
|
+
function removeReaction(thread, commentId, emoji, userId, removedAt) {
|
|
7001
|
+
if (thread.deletedAt !== void 0) {
|
|
7002
|
+
return thread;
|
|
7003
|
+
}
|
|
7004
|
+
const existingComment = thread.comments.find(
|
|
7005
|
+
(comment) => comment.id === commentId
|
|
7006
|
+
);
|
|
7007
|
+
if (existingComment === void 0) {
|
|
7008
|
+
return thread;
|
|
7009
|
+
}
|
|
7010
|
+
if (existingComment.deletedAt !== void 0) {
|
|
7011
|
+
return thread;
|
|
7012
|
+
}
|
|
7013
|
+
const updatedComments = thread.comments.map(
|
|
7014
|
+
(comment) => comment.id === commentId ? {
|
|
7015
|
+
...comment,
|
|
7016
|
+
reactions: comment.reactions.map(
|
|
7017
|
+
(reaction) => reaction.emoji === emoji ? {
|
|
7018
|
+
...reaction,
|
|
7019
|
+
users: reaction.users.filter((user) => user.id !== userId)
|
|
7020
|
+
} : reaction
|
|
7021
|
+
).filter((reaction) => reaction.users.length > 0)
|
|
7022
|
+
// Remove reactions with no users left
|
|
7023
|
+
} : comment
|
|
7024
|
+
);
|
|
7025
|
+
return {
|
|
7026
|
+
...thread,
|
|
7027
|
+
updatedAt: new Date(
|
|
7028
|
+
Math.max(removedAt.getTime(), thread.updatedAt?.getTime() || 0)
|
|
7029
|
+
),
|
|
7030
|
+
comments: updatedComments
|
|
7031
|
+
};
|
|
7032
|
+
}
|
|
7033
|
+
function upsertReaction(reactions, reaction) {
|
|
7034
|
+
const existingReaction = reactions.find(
|
|
7035
|
+
(existingReaction2) => existingReaction2.emoji === reaction.emoji
|
|
7036
|
+
);
|
|
7037
|
+
if (existingReaction === void 0) {
|
|
7038
|
+
return [
|
|
7039
|
+
...reactions,
|
|
7040
|
+
{
|
|
7041
|
+
emoji: reaction.emoji,
|
|
7042
|
+
createdAt: reaction.createdAt,
|
|
7043
|
+
users: [{ id: reaction.userId }]
|
|
7044
|
+
}
|
|
7045
|
+
];
|
|
7046
|
+
}
|
|
7047
|
+
if (existingReaction.users.some((user) => user.id === reaction.userId) === false) {
|
|
7048
|
+
return reactions.map(
|
|
7049
|
+
(existingReaction2) => existingReaction2.emoji === reaction.emoji ? {
|
|
7050
|
+
...existingReaction2,
|
|
7051
|
+
users: [...existingReaction2.users, { id: reaction.userId }]
|
|
7052
|
+
} : existingReaction2
|
|
7053
|
+
);
|
|
7054
|
+
}
|
|
7055
|
+
return reactions;
|
|
7056
|
+
}
|
|
6913
7057
|
|
|
6914
7058
|
// src/client.ts
|
|
6915
7059
|
var MIN_THROTTLE = 16;
|
|
@@ -7059,7 +7203,7 @@ function createClient(options) {
|
|
|
7059
7203
|
getUnreadInboxNotificationsCount,
|
|
7060
7204
|
markAllInboxNotificationsAsRead,
|
|
7061
7205
|
markInboxNotificationAsRead
|
|
7062
|
-
} =
|
|
7206
|
+
} = createNotificationsApi({
|
|
7063
7207
|
baseUrl,
|
|
7064
7208
|
fetcher: clientOptions.polyfills?.fetch || /* istanbul ignore next */
|
|
7065
7209
|
fetch,
|
|
@@ -7104,13 +7248,14 @@ function createClient(options) {
|
|
|
7104
7248
|
leave: forceLeave,
|
|
7105
7249
|
// New, preferred API
|
|
7106
7250
|
enterRoom,
|
|
7107
|
-
// Notifications API
|
|
7108
|
-
getInboxNotifications,
|
|
7109
|
-
getUnreadInboxNotificationsCount,
|
|
7110
|
-
markAllInboxNotificationsAsRead,
|
|
7111
|
-
markInboxNotificationAsRead,
|
|
7112
7251
|
// Internal
|
|
7113
7252
|
[kInternal]: {
|
|
7253
|
+
notifications: {
|
|
7254
|
+
getInboxNotifications,
|
|
7255
|
+
getUnreadInboxNotificationsCount,
|
|
7256
|
+
markAllInboxNotificationsAsRead,
|
|
7257
|
+
markInboxNotificationAsRead
|
|
7258
|
+
},
|
|
7114
7259
|
currentUserIdStore,
|
|
7115
7260
|
resolveMentionSuggestions: clientOptions.resolveMentionSuggestions,
|
|
7116
7261
|
cacheStore,
|
|
@@ -7961,6 +8106,7 @@ export {
|
|
|
7961
8106
|
ServerMsgCode,
|
|
7962
8107
|
WebsocketCloseCodes,
|
|
7963
8108
|
ackOp,
|
|
8109
|
+
addReaction,
|
|
7964
8110
|
applyOptimisticUpdates,
|
|
7965
8111
|
asPos,
|
|
7966
8112
|
assert,
|
|
@@ -7972,6 +8118,7 @@ export {
|
|
|
7972
8118
|
convertToCommentUserReaction,
|
|
7973
8119
|
convertToThreadData,
|
|
7974
8120
|
createClient,
|
|
8121
|
+
deleteComment,
|
|
7975
8122
|
deprecate,
|
|
7976
8123
|
deprecateIf,
|
|
7977
8124
|
detectDupes,
|
|
@@ -7994,12 +8141,14 @@ export {
|
|
|
7994
8141
|
nn,
|
|
7995
8142
|
patchLiveObjectKey,
|
|
7996
8143
|
raise,
|
|
8144
|
+
removeReaction,
|
|
7997
8145
|
shallow,
|
|
7998
8146
|
stringify,
|
|
7999
8147
|
stringifyCommentBody,
|
|
8000
8148
|
throwUsageError,
|
|
8001
8149
|
toPlainLson,
|
|
8002
8150
|
tryParseJson,
|
|
8151
|
+
upsertComment,
|
|
8003
8152
|
withTimeout
|
|
8004
8153
|
};
|
|
8005
8154
|
//# sourceMappingURL=index.mjs.map
|