@liveblocks/core 1.10.0-beta2 → 1.10.0-beta4
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 +77 -69
- package/dist/index.d.ts +77 -69
- package/dist/index.js +573 -288
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +511 -226
- 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-beta4";
|
|
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) => ({
|
|
@@ -1325,7 +1342,7 @@ function createAuthManager(authOptions) {
|
|
|
1325
1342
|
}
|
|
1326
1343
|
return false;
|
|
1327
1344
|
}
|
|
1328
|
-
function getCachedToken(
|
|
1345
|
+
function getCachedToken(requestOptions) {
|
|
1329
1346
|
const now = Math.ceil(Date.now() / 1e3);
|
|
1330
1347
|
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
1331
1348
|
const token = tokens[i];
|
|
@@ -1338,11 +1355,15 @@ 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 */) {
|
|
1341
|
-
if (!
|
|
1358
|
+
if (!requestOptions.roomId && Object.entries(token.parsed.perms).length === 0) {
|
|
1342
1359
|
return token;
|
|
1343
1360
|
}
|
|
1344
1361
|
for (const [resource, scopes] of Object.entries(token.parsed.perms)) {
|
|
1345
|
-
if (
|
|
1362
|
+
if (!requestOptions.roomId) {
|
|
1363
|
+
if (resource.includes("*") && hasCorrespondingScopes(requestOptions.requestedScope, scopes)) {
|
|
1364
|
+
return token;
|
|
1365
|
+
}
|
|
1366
|
+
} else if (resource.includes("*") && requestOptions.roomId.startsWith(resource.replace("*", "")) || requestOptions.roomId === resource && hasCorrespondingScopes(requestOptions.requestedScope, scopes)) {
|
|
1346
1367
|
return token;
|
|
1347
1368
|
}
|
|
1348
1369
|
}
|
|
@@ -1350,7 +1371,7 @@ function createAuthManager(authOptions) {
|
|
|
1350
1371
|
}
|
|
1351
1372
|
return void 0;
|
|
1352
1373
|
}
|
|
1353
|
-
async function makeAuthRequest(
|
|
1374
|
+
async function makeAuthRequest(options) {
|
|
1354
1375
|
const fetcher = authOptions.polyfills?.fetch ?? (typeof window === "undefined" ? void 0 : window.fetch);
|
|
1355
1376
|
if (authentication.type === "private") {
|
|
1356
1377
|
if (fetcher === void 0) {
|
|
@@ -1359,9 +1380,10 @@ function createAuthManager(authOptions) {
|
|
|
1359
1380
|
);
|
|
1360
1381
|
}
|
|
1361
1382
|
const response = await fetchAuthEndpoint(fetcher, authentication.url, {
|
|
1362
|
-
room: roomId
|
|
1383
|
+
room: options.roomId
|
|
1363
1384
|
});
|
|
1364
1385
|
const parsed = parseAuthToken(response.token);
|
|
1386
|
+
verifyTokenPermissions(parsed, options);
|
|
1365
1387
|
if (seenTokens.has(parsed.raw)) {
|
|
1366
1388
|
throw new StopRetrying(
|
|
1367
1389
|
"The same Liveblocks auth token was issued from the backend before. Caching Liveblocks tokens is not supported."
|
|
@@ -1370,10 +1392,12 @@ function createAuthManager(authOptions) {
|
|
|
1370
1392
|
return parsed;
|
|
1371
1393
|
}
|
|
1372
1394
|
if (authentication.type === "custom") {
|
|
1373
|
-
const response = await authentication.callback(roomId);
|
|
1395
|
+
const response = await authentication.callback(options.roomId);
|
|
1374
1396
|
if (response && typeof response === "object") {
|
|
1375
1397
|
if (typeof response.token === "string") {
|
|
1376
|
-
|
|
1398
|
+
const parsed = parseAuthToken(response.token);
|
|
1399
|
+
verifyTokenPermissions(parsed, options);
|
|
1400
|
+
return parsed;
|
|
1377
1401
|
} else if (typeof response.error === "string") {
|
|
1378
1402
|
const reason = `Authentication failed: ${"reason" in response && typeof response.reason === "string" ? response.reason : "Forbidden"}`;
|
|
1379
1403
|
if (response.error === "forbidden") {
|
|
@@ -1391,25 +1415,42 @@ function createAuthManager(authOptions) {
|
|
|
1391
1415
|
"Unexpected authentication type. Must be private or custom."
|
|
1392
1416
|
);
|
|
1393
1417
|
}
|
|
1394
|
-
|
|
1418
|
+
function verifyTokenPermissions(parsedToken, options) {
|
|
1419
|
+
if (!options.roomId && parsedToken.parsed.k === "acc" /* ACCESS_TOKEN */) {
|
|
1420
|
+
if (Object.entries(parsedToken.parsed.perms).length === 0) {
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
for (const [resource, scopes] of Object.entries(
|
|
1424
|
+
parsedToken.parsed.perms
|
|
1425
|
+
)) {
|
|
1426
|
+
if (resource.includes("*") && hasCorrespondingScopes(options.requestedScope, scopes)) {
|
|
1427
|
+
return;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
throw new StopRetrying(
|
|
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"
|
|
1432
|
+
);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
async function getAuthValue(requestOptions) {
|
|
1395
1436
|
if (authentication.type === "public") {
|
|
1396
1437
|
return { type: "public", publicApiKey: authentication.publicApiKey };
|
|
1397
1438
|
}
|
|
1398
|
-
const cachedToken = getCachedToken(
|
|
1439
|
+
const cachedToken = getCachedToken(requestOptions);
|
|
1399
1440
|
if (cachedToken !== void 0) {
|
|
1400
1441
|
return { type: "secret", token: cachedToken };
|
|
1401
1442
|
}
|
|
1402
1443
|
let currentPromise;
|
|
1403
|
-
if (
|
|
1404
|
-
currentPromise = requestPromises.get(
|
|
1444
|
+
if (requestOptions.roomId) {
|
|
1445
|
+
currentPromise = requestPromises.get(requestOptions.roomId);
|
|
1405
1446
|
if (currentPromise === void 0) {
|
|
1406
|
-
currentPromise = makeAuthRequest(
|
|
1407
|
-
requestPromises.set(
|
|
1447
|
+
currentPromise = makeAuthRequest(requestOptions);
|
|
1448
|
+
requestPromises.set(requestOptions.roomId, currentPromise);
|
|
1408
1449
|
}
|
|
1409
1450
|
} else {
|
|
1410
1451
|
currentPromise = requestPromises.get("liveblocks-user-token");
|
|
1411
1452
|
if (currentPromise === void 0) {
|
|
1412
|
-
currentPromise = makeAuthRequest();
|
|
1453
|
+
currentPromise = makeAuthRequest(requestOptions);
|
|
1413
1454
|
requestPromises.set("liveblocks-user-token", currentPromise);
|
|
1414
1455
|
}
|
|
1415
1456
|
}
|
|
@@ -1424,8 +1465,8 @@ function createAuthManager(authOptions) {
|
|
|
1424
1465
|
}
|
|
1425
1466
|
return { type: "secret", token };
|
|
1426
1467
|
} finally {
|
|
1427
|
-
if (
|
|
1428
|
-
requestPromises.delete(
|
|
1468
|
+
if (requestOptions.roomId) {
|
|
1469
|
+
requestPromises.delete(requestOptions.roomId);
|
|
1429
1470
|
} else {
|
|
1430
1471
|
requestPromises.delete("liveblocks-user-token");
|
|
1431
1472
|
}
|
|
@@ -1996,22 +2037,56 @@ function convertToInboxNotificationData(data) {
|
|
|
1996
2037
|
readAt
|
|
1997
2038
|
};
|
|
1998
2039
|
}
|
|
2040
|
+
function convertToThreadDeleteInfo(data) {
|
|
2041
|
+
const deletedAt = new Date(data.deletedAt);
|
|
2042
|
+
return {
|
|
2043
|
+
...data,
|
|
2044
|
+
deletedAt
|
|
2045
|
+
};
|
|
2046
|
+
}
|
|
2047
|
+
function convertToInboxNotificationDeleteInfo(data) {
|
|
2048
|
+
const deletedAt = new Date(data.deletedAt);
|
|
2049
|
+
return {
|
|
2050
|
+
...data,
|
|
2051
|
+
deletedAt
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// src/lib/url.ts
|
|
2056
|
+
function toURLSearchParams(params) {
|
|
2057
|
+
const result = new URLSearchParams();
|
|
2058
|
+
for (const [key, value] of Object.entries(params)) {
|
|
2059
|
+
if (value !== void 0 && value !== null) {
|
|
2060
|
+
result.set(key, value.toString());
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
return result;
|
|
2064
|
+
}
|
|
2065
|
+
function urljoin(baseUrl, path, params) {
|
|
2066
|
+
const url = new URL(path, baseUrl);
|
|
2067
|
+
if (params !== void 0) {
|
|
2068
|
+
url.search = (params instanceof URLSearchParams ? params : toURLSearchParams(params)).toString();
|
|
2069
|
+
}
|
|
2070
|
+
return url.toString();
|
|
2071
|
+
}
|
|
1999
2072
|
|
|
2000
2073
|
// src/notifications.ts
|
|
2001
2074
|
var MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY = 50;
|
|
2002
|
-
function
|
|
2075
|
+
function createNotificationsApi({
|
|
2003
2076
|
baseUrl,
|
|
2004
2077
|
authManager,
|
|
2005
2078
|
currentUserIdStore,
|
|
2006
2079
|
fetcher
|
|
2007
2080
|
}) {
|
|
2008
|
-
async function fetchJson(endpoint, options) {
|
|
2009
|
-
const authValue = await authManager.getAuthValue(
|
|
2081
|
+
async function fetchJson(endpoint, options, params) {
|
|
2082
|
+
const authValue = await authManager.getAuthValue({
|
|
2083
|
+
requestedScope: "comments:read"
|
|
2084
|
+
});
|
|
2010
2085
|
if (authValue.type === "secret" && authValue.token.parsed.k === "acc" /* ACCESS_TOKEN */) {
|
|
2011
2086
|
const userId = authValue.token.parsed.uid;
|
|
2012
2087
|
currentUserIdStore.set(() => userId);
|
|
2013
2088
|
}
|
|
2014
|
-
const url =
|
|
2089
|
+
const url = urljoin(baseUrl, `/v2/c${endpoint}`, params);
|
|
2015
2090
|
const response = await fetcher(url.toString(), {
|
|
2016
2091
|
...options,
|
|
2017
2092
|
headers: {
|
|
@@ -2047,13 +2122,24 @@ function createInboxNotificationsApi({
|
|
|
2047
2122
|
return body;
|
|
2048
2123
|
}
|
|
2049
2124
|
async function getInboxNotifications(options) {
|
|
2050
|
-
const
|
|
2051
|
-
|
|
2125
|
+
const json = await fetchJson("/inbox-notifications", void 0, {
|
|
2126
|
+
limit: options?.limit,
|
|
2127
|
+
since: options?.since?.toISOString()
|
|
2128
|
+
});
|
|
2052
2129
|
return {
|
|
2053
2130
|
threads: json.threads.map((thread) => convertToThreadData(thread)),
|
|
2054
2131
|
inboxNotifications: json.inboxNotifications.map(
|
|
2055
2132
|
(notification) => convertToInboxNotificationData(notification)
|
|
2056
|
-
)
|
|
2133
|
+
),
|
|
2134
|
+
deletedThreads: json.deletedThreads.map(
|
|
2135
|
+
(info) => convertToThreadDeleteInfo(info)
|
|
2136
|
+
),
|
|
2137
|
+
deletedInboxNotifications: json.deletedInboxNotifications.map(
|
|
2138
|
+
(info) => convertToInboxNotificationDeleteInfo(info)
|
|
2139
|
+
),
|
|
2140
|
+
meta: {
|
|
2141
|
+
requestedAt: new Date(json.meta.requestedAt)
|
|
2142
|
+
}
|
|
2057
2143
|
};
|
|
2058
2144
|
}
|
|
2059
2145
|
async function getUnreadInboxNotificationsCount() {
|
|
@@ -2096,15 +2182,6 @@ function createInboxNotificationsApi({
|
|
|
2096
2182
|
markInboxNotificationAsRead
|
|
2097
2183
|
};
|
|
2098
2184
|
}
|
|
2099
|
-
function toURLSearchParams(params) {
|
|
2100
|
-
const result = new URLSearchParams();
|
|
2101
|
-
for (const [key, value] of Object.entries(params)) {
|
|
2102
|
-
if (value !== void 0 && value !== null) {
|
|
2103
|
-
result.set(key, value.toString());
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
return result;
|
|
2107
|
-
}
|
|
2108
2185
|
|
|
2109
2186
|
// src/lib/position.ts
|
|
2110
2187
|
var MIN_CODE = 32;
|
|
@@ -4959,12 +5036,12 @@ var CommentsApiError = class extends Error {
|
|
|
4959
5036
|
}
|
|
4960
5037
|
};
|
|
4961
5038
|
function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
4962
|
-
async function fetchCommentsApi(endpoint, options) {
|
|
5039
|
+
async function fetchCommentsApi(endpoint, params, options) {
|
|
4963
5040
|
const authValue = await getAuthValue();
|
|
4964
|
-
return fetchClientApi(roomId, endpoint, authValue, options);
|
|
5041
|
+
return fetchClientApi(roomId, endpoint, authValue, options, params);
|
|
4965
5042
|
}
|
|
4966
|
-
async function fetchJson(endpoint, options) {
|
|
4967
|
-
const response = await fetchCommentsApi(endpoint, options);
|
|
5043
|
+
async function fetchJson(endpoint, options, params) {
|
|
5044
|
+
const response = await fetchCommentsApi(endpoint, params, options);
|
|
4968
5045
|
if (!response.ok) {
|
|
4969
5046
|
if (response.status >= 400 && response.status < 600) {
|
|
4970
5047
|
let error3;
|
|
@@ -4990,25 +5067,48 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
4990
5067
|
return body;
|
|
4991
5068
|
}
|
|
4992
5069
|
async function getThreads(options) {
|
|
4993
|
-
const response = await fetchCommentsApi(
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
headers: {
|
|
4998
|
-
"Content-Type": "application/json"
|
|
5070
|
+
const response = await fetchCommentsApi(
|
|
5071
|
+
"/threads/search",
|
|
5072
|
+
{
|
|
5073
|
+
since: options?.since?.toISOString()
|
|
4999
5074
|
},
|
|
5000
|
-
|
|
5001
|
-
|
|
5075
|
+
{
|
|
5076
|
+
body: JSON.stringify({
|
|
5077
|
+
...options?.query?.metadata && { metadata: options.query.metadata }
|
|
5078
|
+
}),
|
|
5079
|
+
headers: {
|
|
5080
|
+
"Content-Type": "application/json"
|
|
5081
|
+
},
|
|
5082
|
+
method: "POST"
|
|
5083
|
+
}
|
|
5084
|
+
);
|
|
5002
5085
|
if (response.ok) {
|
|
5003
5086
|
const json = await response.json();
|
|
5004
5087
|
return {
|
|
5005
5088
|
threads: json.data.map((thread) => convertToThreadData(thread)),
|
|
5006
5089
|
inboxNotifications: json.inboxNotifications.map(
|
|
5007
5090
|
(notification) => convertToInboxNotificationData(notification)
|
|
5008
|
-
)
|
|
5091
|
+
),
|
|
5092
|
+
deletedThreads: json.deletedThreads.map(
|
|
5093
|
+
(info) => convertToThreadDeleteInfo(info)
|
|
5094
|
+
),
|
|
5095
|
+
deletedInboxNotifications: json.deletedInboxNotifications.map(
|
|
5096
|
+
(info) => convertToInboxNotificationDeleteInfo(info)
|
|
5097
|
+
),
|
|
5098
|
+
meta: {
|
|
5099
|
+
requestedAt: new Date(json.meta.requestedAt)
|
|
5100
|
+
}
|
|
5009
5101
|
};
|
|
5010
5102
|
} else if (response.status === 404) {
|
|
5011
|
-
return {
|
|
5103
|
+
return {
|
|
5104
|
+
threads: [],
|
|
5105
|
+
inboxNotifications: [],
|
|
5106
|
+
deletedThreads: [],
|
|
5107
|
+
deletedInboxNotifications: [],
|
|
5108
|
+
meta: {
|
|
5109
|
+
requestedAt: /* @__PURE__ */ new Date()
|
|
5110
|
+
}
|
|
5111
|
+
};
|
|
5012
5112
|
} else {
|
|
5013
5113
|
throw new Error("There was an error while getting threads.");
|
|
5014
5114
|
}
|
|
@@ -5110,7 +5210,7 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5110
5210
|
);
|
|
5111
5211
|
return convertToCommentData(comment);
|
|
5112
5212
|
}
|
|
5113
|
-
async function
|
|
5213
|
+
async function deleteComment2({
|
|
5114
5214
|
threadId,
|
|
5115
5215
|
commentId
|
|
5116
5216
|
}) {
|
|
@@ -5123,7 +5223,7 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5123
5223
|
}
|
|
5124
5224
|
);
|
|
5125
5225
|
}
|
|
5126
|
-
async function
|
|
5226
|
+
async function addReaction2({
|
|
5127
5227
|
threadId,
|
|
5128
5228
|
commentId,
|
|
5129
5229
|
emoji
|
|
@@ -5142,7 +5242,7 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5142
5242
|
);
|
|
5143
5243
|
return convertToCommentUserReaction(reaction);
|
|
5144
5244
|
}
|
|
5145
|
-
async function
|
|
5245
|
+
async function removeReaction2({
|
|
5146
5246
|
threadId,
|
|
5147
5247
|
commentId,
|
|
5148
5248
|
emoji
|
|
@@ -5163,11 +5263,12 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5163
5263
|
editThreadMetadata,
|
|
5164
5264
|
createComment,
|
|
5165
5265
|
editComment,
|
|
5166
|
-
deleteComment,
|
|
5167
|
-
addReaction,
|
|
5168
|
-
removeReaction
|
|
5266
|
+
deleteComment: deleteComment2,
|
|
5267
|
+
addReaction: addReaction2,
|
|
5268
|
+
removeReaction: removeReaction2
|
|
5169
5269
|
};
|
|
5170
5270
|
}
|
|
5271
|
+
var MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY2 = 50;
|
|
5171
5272
|
function createRoom(options, config) {
|
|
5172
5273
|
const initialPresence = typeof options.initialPresence === "function" ? options.initialPresence(config.roomId) : options.initialPresence;
|
|
5173
5274
|
const initialStorage = typeof options.initialStorage === "function" ? options.initialStorage(config.roomId) : options.initialStorage;
|
|
@@ -5383,14 +5484,15 @@ function createRoom(options, config) {
|
|
|
5383
5484
|
ydoc: makeEventSource(),
|
|
5384
5485
|
comments: makeEventSource()
|
|
5385
5486
|
};
|
|
5386
|
-
async function fetchClientApi(roomId, endpoint, authValue, options2) {
|
|
5387
|
-
const url =
|
|
5487
|
+
async function fetchClientApi(roomId, endpoint, authValue, options2, params) {
|
|
5488
|
+
const url = urljoin(
|
|
5489
|
+
config.baseUrl,
|
|
5388
5490
|
`/v2/c/rooms/${encodeURIComponent(roomId)}${endpoint}`,
|
|
5389
|
-
|
|
5491
|
+
params
|
|
5390
5492
|
);
|
|
5391
5493
|
const fetcher = config.polyfills?.fetch || /* istanbul ignore next */
|
|
5392
5494
|
fetch;
|
|
5393
|
-
return await fetcher(url
|
|
5495
|
+
return await fetcher(url, {
|
|
5394
5496
|
...options2,
|
|
5395
5497
|
headers: {
|
|
5396
5498
|
...options2?.headers,
|
|
@@ -6218,7 +6320,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6218
6320
|
delegates.authenticate,
|
|
6219
6321
|
fetchClientApi
|
|
6220
6322
|
);
|
|
6221
|
-
async function
|
|
6323
|
+
async function fetchNotificationsJson(endpoint, options2) {
|
|
6222
6324
|
const authValue = await delegates.authenticate();
|
|
6223
6325
|
const response = await fetchClientApi(
|
|
6224
6326
|
config.roomId,
|
|
@@ -6228,16 +6330,21 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6228
6330
|
);
|
|
6229
6331
|
if (!response.ok) {
|
|
6230
6332
|
if (response.status >= 400 && response.status < 600) {
|
|
6231
|
-
let
|
|
6333
|
+
let error3;
|
|
6232
6334
|
try {
|
|
6233
6335
|
const errorBody = await response.json();
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
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
|
+
);
|
|
6237
6346
|
}
|
|
6238
|
-
throw
|
|
6239
|
-
`Request failed with status ${response.status}: ${errorMessage}`
|
|
6240
|
-
);
|
|
6347
|
+
throw error3;
|
|
6241
6348
|
}
|
|
6242
6349
|
}
|
|
6243
6350
|
let body;
|
|
@@ -6249,20 +6356,44 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6249
6356
|
return body;
|
|
6250
6357
|
}
|
|
6251
6358
|
function getRoomNotificationSettings() {
|
|
6252
|
-
return
|
|
6359
|
+
return fetchNotificationsJson(
|
|
6360
|
+
"/notification-settings"
|
|
6361
|
+
);
|
|
6253
6362
|
}
|
|
6254
6363
|
function updateRoomNotificationSettings(settings) {
|
|
6255
|
-
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", {
|
|
6256
6377
|
method: "POST",
|
|
6257
|
-
body: JSON.stringify(settings),
|
|
6258
6378
|
headers: {
|
|
6259
6379
|
"Content-Type": "application/json"
|
|
6260
|
-
}
|
|
6380
|
+
},
|
|
6381
|
+
body: JSON.stringify({ inboxNotificationIds })
|
|
6261
6382
|
});
|
|
6262
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
|
+
}
|
|
6263
6395
|
return Object.defineProperty(
|
|
6264
6396
|
{
|
|
6265
|
-
/* NOTE: Exposing internals here only to allow testing implementation details in unit tests */
|
|
6266
6397
|
[kInternal]: {
|
|
6267
6398
|
get presenceBuffer() {
|
|
6268
6399
|
return deepClone(context.buffer.presenceUpdates?.data ?? null);
|
|
@@ -6284,6 +6415,14 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6284
6415
|
// These exist only for our E2E testing app
|
|
6285
6416
|
explicitClose: (event) => managedSocket._privateSendMachineEvent({ type: "EXPLICIT_SOCKET_CLOSE", event }),
|
|
6286
6417
|
rawSend: (data) => managedSocket.send(data)
|
|
6418
|
+
},
|
|
6419
|
+
comments: {
|
|
6420
|
+
...commentsApi
|
|
6421
|
+
},
|
|
6422
|
+
notifications: {
|
|
6423
|
+
getRoomNotificationSettings,
|
|
6424
|
+
updateRoomNotificationSettings,
|
|
6425
|
+
markInboxNotificationAsRead
|
|
6287
6426
|
}
|
|
6288
6427
|
},
|
|
6289
6428
|
id: config.roomId,
|
|
@@ -6321,12 +6460,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6321
6460
|
getSelf: () => self.current,
|
|
6322
6461
|
// Presence
|
|
6323
6462
|
getPresence: () => context.myPresence.current,
|
|
6324
|
-
getOthers: () => context.others.current
|
|
6325
|
-
// Comments
|
|
6326
|
-
...commentsApi,
|
|
6327
|
-
// Notifications
|
|
6328
|
-
getRoomNotificationSettings,
|
|
6329
|
-
updateRoomNotificationSettings
|
|
6463
|
+
getOthers: () => context.others.current
|
|
6330
6464
|
},
|
|
6331
6465
|
// Explictly make the internal field non-enumerable, to avoid aggressive
|
|
6332
6466
|
// freezing when used with Immer
|
|
@@ -6466,28 +6600,6 @@ function createClientStore() {
|
|
|
6466
6600
|
inboxNotifications: {},
|
|
6467
6601
|
notificationSettings: {}
|
|
6468
6602
|
});
|
|
6469
|
-
function mergeThreads(existingThreads, newThreads) {
|
|
6470
|
-
const updatedThreads = { ...existingThreads };
|
|
6471
|
-
Object.entries(newThreads).forEach(([id, thread]) => {
|
|
6472
|
-
const existingThread = updatedThreads[id];
|
|
6473
|
-
if (existingThread) {
|
|
6474
|
-
const result = compareThreads(existingThread, thread);
|
|
6475
|
-
if (result === 1)
|
|
6476
|
-
return;
|
|
6477
|
-
}
|
|
6478
|
-
updatedThreads[id] = thread;
|
|
6479
|
-
});
|
|
6480
|
-
return updatedThreads;
|
|
6481
|
-
}
|
|
6482
|
-
function mergeNotifications(existingInboxNotifications, newInboxNotifications) {
|
|
6483
|
-
const inboxNotifications = Object.values({
|
|
6484
|
-
...existingInboxNotifications,
|
|
6485
|
-
...newInboxNotifications
|
|
6486
|
-
});
|
|
6487
|
-
return Object.fromEntries(
|
|
6488
|
-
inboxNotifications.map((notification) => [notification.id, notification])
|
|
6489
|
-
);
|
|
6490
|
-
}
|
|
6491
6603
|
return {
|
|
6492
6604
|
...store,
|
|
6493
6605
|
deleteThread(threadId) {
|
|
@@ -6516,21 +6628,19 @@ function createClientStore() {
|
|
|
6516
6628
|
};
|
|
6517
6629
|
});
|
|
6518
6630
|
},
|
|
6519
|
-
updateThreadsAndNotifications(threads, inboxNotifications, queryKey) {
|
|
6631
|
+
updateThreadsAndNotifications(threads, inboxNotifications, deletedThreads, deletedInboxNotifications, queryKey) {
|
|
6520
6632
|
store.set((state) => ({
|
|
6521
6633
|
...state,
|
|
6522
|
-
threads:
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
),
|
|
6526
|
-
inboxNotifications:
|
|
6634
|
+
threads: applyThreadUpdates(state.threads, {
|
|
6635
|
+
newThreads: threads,
|
|
6636
|
+
deletedThreads
|
|
6637
|
+
}),
|
|
6638
|
+
inboxNotifications: applyNotificationsUpdates(
|
|
6527
6639
|
state.inboxNotifications,
|
|
6528
|
-
|
|
6529
|
-
inboxNotifications
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
])
|
|
6533
|
-
)
|
|
6640
|
+
{
|
|
6641
|
+
newInboxNotifications: inboxNotifications,
|
|
6642
|
+
deletedNotifications: deletedInboxNotifications
|
|
6643
|
+
}
|
|
6534
6644
|
),
|
|
6535
6645
|
queries: queryKey !== void 0 ? {
|
|
6536
6646
|
...state.queries,
|
|
@@ -6540,6 +6650,21 @@ function createClientStore() {
|
|
|
6540
6650
|
} : state.queries
|
|
6541
6651
|
}));
|
|
6542
6652
|
},
|
|
6653
|
+
updateRoomInboxNotificationSettings(roomId, settings, queryKey) {
|
|
6654
|
+
store.set((state) => ({
|
|
6655
|
+
...state,
|
|
6656
|
+
notificationSettings: {
|
|
6657
|
+
...state.notificationSettings,
|
|
6658
|
+
[roomId]: settings
|
|
6659
|
+
},
|
|
6660
|
+
queries: {
|
|
6661
|
+
...state.queries,
|
|
6662
|
+
[queryKey]: {
|
|
6663
|
+
isLoading: false
|
|
6664
|
+
}
|
|
6665
|
+
}
|
|
6666
|
+
}));
|
|
6667
|
+
},
|
|
6543
6668
|
pushOptimisticUpdate(optimisticUpdate) {
|
|
6544
6669
|
store.set((state) => ({
|
|
6545
6670
|
...state,
|
|
@@ -6600,8 +6725,15 @@ function applyOptimisticUpdates(state) {
|
|
|
6600
6725
|
if (thread === void 0) {
|
|
6601
6726
|
break;
|
|
6602
6727
|
}
|
|
6728
|
+
if (thread.deletedAt !== void 0) {
|
|
6729
|
+
break;
|
|
6730
|
+
}
|
|
6731
|
+
if (thread.updatedAt !== void 0 && thread.updatedAt > optimisticUpdate.updatedAt) {
|
|
6732
|
+
break;
|
|
6733
|
+
}
|
|
6603
6734
|
result.threads[thread.id] = {
|
|
6604
6735
|
...thread,
|
|
6736
|
+
updatedAt: optimisticUpdate.updatedAt,
|
|
6605
6737
|
metadata: {
|
|
6606
6738
|
...thread.metadata,
|
|
6607
6739
|
...optimisticUpdate.metadata
|
|
@@ -6614,16 +6746,17 @@ function applyOptimisticUpdates(state) {
|
|
|
6614
6746
|
if (thread === void 0) {
|
|
6615
6747
|
break;
|
|
6616
6748
|
}
|
|
6617
|
-
result.threads[thread.id] =
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
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) {
|
|
6623
6757
|
break;
|
|
6624
6758
|
}
|
|
6625
|
-
|
|
6626
|
-
result.inboxNotifications[optimisticUpdate.inboxNotificationId] = {
|
|
6759
|
+
result.inboxNotifications[inboxNotification.id] = {
|
|
6627
6760
|
...inboxNotification,
|
|
6628
6761
|
notifiedAt: optimisticUpdate.comment.createdAt,
|
|
6629
6762
|
readAt: optimisticUpdate.comment.createdAt
|
|
@@ -6631,20 +6764,14 @@ function applyOptimisticUpdates(state) {
|
|
|
6631
6764
|
break;
|
|
6632
6765
|
}
|
|
6633
6766
|
case "edit-comment": {
|
|
6634
|
-
const thread = result.threads[optimisticUpdate.threadId];
|
|
6767
|
+
const thread = result.threads[optimisticUpdate.comment.threadId];
|
|
6635
6768
|
if (thread === void 0) {
|
|
6636
6769
|
break;
|
|
6637
6770
|
}
|
|
6638
|
-
result.threads[thread.id] =
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
...comment,
|
|
6643
|
-
editedAt: optimisticUpdate.editedAt,
|
|
6644
|
-
body: optimisticUpdate.body
|
|
6645
|
-
} : comment
|
|
6646
|
-
)
|
|
6647
|
-
};
|
|
6771
|
+
result.threads[thread.id] = upsertComment(
|
|
6772
|
+
thread,
|
|
6773
|
+
optimisticUpdate.comment
|
|
6774
|
+
);
|
|
6648
6775
|
break;
|
|
6649
6776
|
}
|
|
6650
6777
|
case "delete-comment": {
|
|
@@ -6652,21 +6779,11 @@ function applyOptimisticUpdates(state) {
|
|
|
6652
6779
|
if (thread === void 0) {
|
|
6653
6780
|
break;
|
|
6654
6781
|
}
|
|
6655
|
-
result.threads[thread.id] =
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
deletedAt: optimisticUpdate.deletedAt,
|
|
6661
|
-
body: void 0
|
|
6662
|
-
} : comment
|
|
6663
|
-
)
|
|
6664
|
-
};
|
|
6665
|
-
if (!result.threads[thread.id].comments.some(
|
|
6666
|
-
(comment) => comment.deletedAt === void 0
|
|
6667
|
-
)) {
|
|
6668
|
-
delete result.threads[thread.id];
|
|
6669
|
-
}
|
|
6782
|
+
result.threads[thread.id] = deleteComment(
|
|
6783
|
+
thread,
|
|
6784
|
+
optimisticUpdate.commentId,
|
|
6785
|
+
optimisticUpdate.deletedAt
|
|
6786
|
+
);
|
|
6670
6787
|
break;
|
|
6671
6788
|
}
|
|
6672
6789
|
case "add-reaction": {
|
|
@@ -6674,43 +6791,11 @@ function applyOptimisticUpdates(state) {
|
|
|
6674
6791
|
if (thread === void 0) {
|
|
6675
6792
|
break;
|
|
6676
6793
|
}
|
|
6677
|
-
result.threads[thread.id] =
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
(reaction) => reaction.emoji === optimisticUpdate.emoji
|
|
6683
|
-
)) {
|
|
6684
|
-
return {
|
|
6685
|
-
...comment,
|
|
6686
|
-
reactions: comment.reactions.map(
|
|
6687
|
-
(reaction) => reaction.emoji === optimisticUpdate.emoji ? {
|
|
6688
|
-
...reaction,
|
|
6689
|
-
users: [
|
|
6690
|
-
...reaction.users,
|
|
6691
|
-
{ id: optimisticUpdate.userId }
|
|
6692
|
-
]
|
|
6693
|
-
} : reaction
|
|
6694
|
-
)
|
|
6695
|
-
};
|
|
6696
|
-
} else {
|
|
6697
|
-
return {
|
|
6698
|
-
...comment,
|
|
6699
|
-
reactions: [
|
|
6700
|
-
...comment.reactions,
|
|
6701
|
-
{
|
|
6702
|
-
emoji: optimisticUpdate.emoji,
|
|
6703
|
-
createdAt: optimisticUpdate.createdAt,
|
|
6704
|
-
users: [{ id: optimisticUpdate.userId }]
|
|
6705
|
-
}
|
|
6706
|
-
]
|
|
6707
|
-
};
|
|
6708
|
-
}
|
|
6709
|
-
} else {
|
|
6710
|
-
return comment;
|
|
6711
|
-
}
|
|
6712
|
-
})
|
|
6713
|
-
};
|
|
6794
|
+
result.threads[thread.id] = addReaction(
|
|
6795
|
+
thread,
|
|
6796
|
+
optimisticUpdate.commentId,
|
|
6797
|
+
optimisticUpdate.reaction
|
|
6798
|
+
);
|
|
6714
6799
|
break;
|
|
6715
6800
|
}
|
|
6716
6801
|
case "remove-reaction": {
|
|
@@ -6718,37 +6803,13 @@ function applyOptimisticUpdates(state) {
|
|
|
6718
6803
|
if (thread === void 0) {
|
|
6719
6804
|
break;
|
|
6720
6805
|
}
|
|
6721
|
-
result.threads[thread.id] =
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
(reaction) => reaction.emoji === optimisticUpdate.emoji
|
|
6729
|
-
);
|
|
6730
|
-
let reactions = comment.reactions;
|
|
6731
|
-
if (reactionIndex >= 0 && comment.reactions[reactionIndex].users.some(
|
|
6732
|
-
(user) => user.id === optimisticUpdate.userId
|
|
6733
|
-
)) {
|
|
6734
|
-
if (comment.reactions[reactionIndex].users.length <= 1) {
|
|
6735
|
-
reactions = [...comment.reactions];
|
|
6736
|
-
reactions.splice(reactionIndex, 1);
|
|
6737
|
-
} else {
|
|
6738
|
-
reactions[reactionIndex] = {
|
|
6739
|
-
...reactions[reactionIndex],
|
|
6740
|
-
users: reactions[reactionIndex].users.filter(
|
|
6741
|
-
(user) => user.id !== optimisticUpdate.userId
|
|
6742
|
-
)
|
|
6743
|
-
};
|
|
6744
|
-
}
|
|
6745
|
-
}
|
|
6746
|
-
return {
|
|
6747
|
-
...comment,
|
|
6748
|
-
reactions
|
|
6749
|
-
};
|
|
6750
|
-
})
|
|
6751
|
-
};
|
|
6806
|
+
result.threads[thread.id] = removeReaction(
|
|
6807
|
+
thread,
|
|
6808
|
+
optimisticUpdate.commentId,
|
|
6809
|
+
optimisticUpdate.emoji,
|
|
6810
|
+
optimisticUpdate.userId,
|
|
6811
|
+
optimisticUpdate.removedAt
|
|
6812
|
+
);
|
|
6752
6813
|
break;
|
|
6753
6814
|
}
|
|
6754
6815
|
case "mark-inbox-notification-as-read": {
|
|
@@ -6777,6 +6838,222 @@ function applyOptimisticUpdates(state) {
|
|
|
6777
6838
|
}
|
|
6778
6839
|
return result;
|
|
6779
6840
|
}
|
|
6841
|
+
function applyThreadUpdates(existingThreads, updates) {
|
|
6842
|
+
const updatedThreads = { ...existingThreads };
|
|
6843
|
+
updates.newThreads.forEach((thread) => {
|
|
6844
|
+
const existingThread = updatedThreads[thread.id];
|
|
6845
|
+
if (existingThread) {
|
|
6846
|
+
const result = compareThreads(existingThread, thread);
|
|
6847
|
+
if (result === 1)
|
|
6848
|
+
return;
|
|
6849
|
+
}
|
|
6850
|
+
updatedThreads[thread.id] = thread;
|
|
6851
|
+
});
|
|
6852
|
+
updates.deletedThreads.forEach(({ id, deletedAt }) => {
|
|
6853
|
+
const existingThread = updatedThreads[id];
|
|
6854
|
+
if (existingThread === void 0)
|
|
6855
|
+
return;
|
|
6856
|
+
existingThread.deletedAt = deletedAt;
|
|
6857
|
+
existingThread.updatedAt = deletedAt;
|
|
6858
|
+
existingThread.comments = [];
|
|
6859
|
+
});
|
|
6860
|
+
return updatedThreads;
|
|
6861
|
+
}
|
|
6862
|
+
function applyNotificationsUpdates(existingInboxNotifications, updates) {
|
|
6863
|
+
const updatedInboxNotifications = { ...existingInboxNotifications };
|
|
6864
|
+
updates.newInboxNotifications.forEach((notification) => {
|
|
6865
|
+
const existingNotification = updatedInboxNotifications[notification.id];
|
|
6866
|
+
if (existingNotification) {
|
|
6867
|
+
const result = compareInboxNotifications(
|
|
6868
|
+
existingNotification,
|
|
6869
|
+
notification
|
|
6870
|
+
);
|
|
6871
|
+
if (result === 1)
|
|
6872
|
+
return;
|
|
6873
|
+
}
|
|
6874
|
+
updatedInboxNotifications[notification.id] = notification;
|
|
6875
|
+
});
|
|
6876
|
+
updates.deletedNotifications.forEach(
|
|
6877
|
+
({ id }) => delete updatedInboxNotifications[id]
|
|
6878
|
+
);
|
|
6879
|
+
return updatedInboxNotifications;
|
|
6880
|
+
}
|
|
6881
|
+
function compareInboxNotifications(inboxNotificationA, inboxNotificationB) {
|
|
6882
|
+
if (inboxNotificationA.notifiedAt > inboxNotificationB.notifiedAt) {
|
|
6883
|
+
return 1;
|
|
6884
|
+
} else if (inboxNotificationA.notifiedAt < inboxNotificationB.notifiedAt) {
|
|
6885
|
+
return -1;
|
|
6886
|
+
}
|
|
6887
|
+
if (inboxNotificationA.readAt && inboxNotificationB.readAt) {
|
|
6888
|
+
return inboxNotificationA.readAt > inboxNotificationB.readAt ? 1 : inboxNotificationA.readAt < inboxNotificationB.readAt ? -1 : 0;
|
|
6889
|
+
} else if (inboxNotificationA.readAt || inboxNotificationB.readAt) {
|
|
6890
|
+
return inboxNotificationA.readAt ? 1 : -1;
|
|
6891
|
+
}
|
|
6892
|
+
return 0;
|
|
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
|
+
}
|
|
6780
7057
|
|
|
6781
7058
|
// src/client.ts
|
|
6782
7059
|
var MIN_THROTTLE = 16;
|
|
@@ -6926,7 +7203,7 @@ function createClient(options) {
|
|
|
6926
7203
|
getUnreadInboxNotificationsCount,
|
|
6927
7204
|
markAllInboxNotificationsAsRead,
|
|
6928
7205
|
markInboxNotificationAsRead
|
|
6929
|
-
} =
|
|
7206
|
+
} = createNotificationsApi({
|
|
6930
7207
|
baseUrl,
|
|
6931
7208
|
fetcher: clientOptions.polyfills?.fetch || /* istanbul ignore next */
|
|
6932
7209
|
fetch,
|
|
@@ -6971,18 +7248,22 @@ function createClient(options) {
|
|
|
6971
7248
|
leave: forceLeave,
|
|
6972
7249
|
// New, preferred API
|
|
6973
7250
|
enterRoom,
|
|
6974
|
-
// Notifications API
|
|
6975
|
-
getInboxNotifications,
|
|
6976
|
-
getUnreadInboxNotificationsCount,
|
|
6977
|
-
markAllInboxNotificationsAsRead,
|
|
6978
|
-
markInboxNotificationAsRead,
|
|
6979
7251
|
// Internal
|
|
6980
7252
|
[kInternal]: {
|
|
7253
|
+
notifications: {
|
|
7254
|
+
getInboxNotifications,
|
|
7255
|
+
getUnreadInboxNotificationsCount,
|
|
7256
|
+
markAllInboxNotificationsAsRead,
|
|
7257
|
+
markInboxNotificationAsRead
|
|
7258
|
+
},
|
|
6981
7259
|
currentUserIdStore,
|
|
6982
7260
|
resolveMentionSuggestions: clientOptions.resolveMentionSuggestions,
|
|
6983
7261
|
cacheStore,
|
|
6984
7262
|
usersStore,
|
|
6985
|
-
roomsInfoStore
|
|
7263
|
+
roomsInfoStore,
|
|
7264
|
+
getRoomIds() {
|
|
7265
|
+
return Array.from(roomsById.keys());
|
|
7266
|
+
}
|
|
6986
7267
|
}
|
|
6987
7268
|
},
|
|
6988
7269
|
kInternal,
|
|
@@ -7825,6 +8106,7 @@ export {
|
|
|
7825
8106
|
ServerMsgCode,
|
|
7826
8107
|
WebsocketCloseCodes,
|
|
7827
8108
|
ackOp,
|
|
8109
|
+
addReaction,
|
|
7828
8110
|
applyOptimisticUpdates,
|
|
7829
8111
|
asPos,
|
|
7830
8112
|
assert,
|
|
@@ -7836,6 +8118,7 @@ export {
|
|
|
7836
8118
|
convertToCommentUserReaction,
|
|
7837
8119
|
convertToThreadData,
|
|
7838
8120
|
createClient,
|
|
8121
|
+
deleteComment,
|
|
7839
8122
|
deprecate,
|
|
7840
8123
|
deprecateIf,
|
|
7841
8124
|
detectDupes,
|
|
@@ -7858,12 +8141,14 @@ export {
|
|
|
7858
8141
|
nn,
|
|
7859
8142
|
patchLiveObjectKey,
|
|
7860
8143
|
raise,
|
|
8144
|
+
removeReaction,
|
|
7861
8145
|
shallow,
|
|
7862
8146
|
stringify,
|
|
7863
8147
|
stringifyCommentBody,
|
|
7864
8148
|
throwUsageError,
|
|
7865
8149
|
toPlainLson,
|
|
7866
8150
|
tryParseJson,
|
|
8151
|
+
upsertComment,
|
|
7867
8152
|
withTimeout
|
|
7868
8153
|
};
|
|
7869
8154
|
//# sourceMappingURL=index.mjs.map
|