@liveblocks/core 2.7.1 → 2.8.0-beta1
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 +102 -24
- package/dist/index.d.ts +102 -24
- package/dist/index.js +198 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +173 -12
- 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 = "2.
|
|
9
|
+
var PKG_VERSION = "2.8.0-beta1";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -1871,8 +1871,7 @@ var Batch = class {
|
|
|
1871
1871
|
this.clearDelayTimeout();
|
|
1872
1872
|
}
|
|
1873
1873
|
};
|
|
1874
|
-
function createBatchStore(
|
|
1875
|
-
const batch = new Batch(callback, options);
|
|
1874
|
+
function createBatchStore(batch) {
|
|
1876
1875
|
const cache = /* @__PURE__ */ new Map();
|
|
1877
1876
|
const eventSource2 = makeEventSource();
|
|
1878
1877
|
function getCacheKey(args) {
|
|
@@ -4796,9 +4795,19 @@ function findNonSerializableValue(value, path = "") {
|
|
|
4796
4795
|
return false;
|
|
4797
4796
|
}
|
|
4798
4797
|
|
|
4798
|
+
// src/lib/chunk.ts
|
|
4799
|
+
function chunk(array, size) {
|
|
4800
|
+
const chunks = [];
|
|
4801
|
+
for (let i = 0, j = array.length; i < j; i += size) {
|
|
4802
|
+
chunks.push(array.slice(i, i + size));
|
|
4803
|
+
}
|
|
4804
|
+
return chunks;
|
|
4805
|
+
}
|
|
4806
|
+
|
|
4799
4807
|
// src/lib/createIds.ts
|
|
4800
4808
|
var THREAD_ID_PREFIX = "th";
|
|
4801
4809
|
var COMMENT_ID_PREFIX = "cm";
|
|
4810
|
+
var COMMENT_ATTACHMENT_ID_PREFIX = "at";
|
|
4802
4811
|
var INBOX_NOTIFICATION_ID_PREFIX = "in";
|
|
4803
4812
|
function createOptimisticId(prefix) {
|
|
4804
4813
|
return `${prefix}_${nanoid()}`;
|
|
@@ -4809,6 +4818,9 @@ function createThreadId() {
|
|
|
4809
4818
|
function createCommentId() {
|
|
4810
4819
|
return createOptimisticId(COMMENT_ID_PREFIX);
|
|
4811
4820
|
}
|
|
4821
|
+
function createCommentAttachmentId() {
|
|
4822
|
+
return createOptimisticId(COMMENT_ATTACHMENT_ID_PREFIX);
|
|
4823
|
+
}
|
|
4812
4824
|
function createInboxNotificationId() {
|
|
4813
4825
|
return createOptimisticId(INBOX_NOTIFICATION_ID_PREFIX);
|
|
4814
4826
|
}
|
|
@@ -5211,6 +5223,22 @@ function installBackgroundTabSpy() {
|
|
|
5211
5223
|
};
|
|
5212
5224
|
return [inBackgroundSince, unsub];
|
|
5213
5225
|
}
|
|
5226
|
+
var GET_ATTACHMENT_URLS_BATCH_DELAY = 50;
|
|
5227
|
+
var ATTACHMENT_PART_SIZE = 5 * 1024 * 1024;
|
|
5228
|
+
var ATTACHMENT_PART_BATCH_SIZE = 5;
|
|
5229
|
+
function splitFileIntoParts(file) {
|
|
5230
|
+
const parts = [];
|
|
5231
|
+
let start = 0;
|
|
5232
|
+
while (start < file.size) {
|
|
5233
|
+
const end = Math.min(start + ATTACHMENT_PART_SIZE, file.size);
|
|
5234
|
+
parts.push({
|
|
5235
|
+
partNumber: parts.length + 1,
|
|
5236
|
+
part: file.slice(start, end)
|
|
5237
|
+
});
|
|
5238
|
+
start = end;
|
|
5239
|
+
}
|
|
5240
|
+
return parts;
|
|
5241
|
+
}
|
|
5214
5242
|
var CommentsApiError = class extends Error {
|
|
5215
5243
|
constructor(message, status, details) {
|
|
5216
5244
|
super(message);
|
|
@@ -6504,7 +6532,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6504
6532
|
metadata,
|
|
6505
6533
|
body,
|
|
6506
6534
|
commentId = createCommentId(),
|
|
6507
|
-
threadId = createThreadId()
|
|
6535
|
+
threadId = createThreadId(),
|
|
6536
|
+
attachmentIds
|
|
6508
6537
|
}) {
|
|
6509
6538
|
const thread = await fetchCommentsJson("/threads", {
|
|
6510
6539
|
method: "POST",
|
|
@@ -6515,7 +6544,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6515
6544
|
id: threadId,
|
|
6516
6545
|
comment: {
|
|
6517
6546
|
id: commentId,
|
|
6518
|
-
body
|
|
6547
|
+
body,
|
|
6548
|
+
attachmentIds
|
|
6519
6549
|
},
|
|
6520
6550
|
metadata
|
|
6521
6551
|
})
|
|
@@ -6561,7 +6591,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6561
6591
|
async function createComment({
|
|
6562
6592
|
threadId,
|
|
6563
6593
|
commentId = createCommentId(),
|
|
6564
|
-
body
|
|
6594
|
+
body,
|
|
6595
|
+
attachmentIds
|
|
6565
6596
|
}) {
|
|
6566
6597
|
const comment = await fetchCommentsJson(
|
|
6567
6598
|
`/threads/${encodeURIComponent(threadId)}/comments`,
|
|
@@ -6572,7 +6603,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6572
6603
|
},
|
|
6573
6604
|
body: JSON.stringify({
|
|
6574
6605
|
id: commentId,
|
|
6575
|
-
body
|
|
6606
|
+
body,
|
|
6607
|
+
attachmentIds
|
|
6576
6608
|
})
|
|
6577
6609
|
}
|
|
6578
6610
|
);
|
|
@@ -6581,7 +6613,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6581
6613
|
async function editComment({
|
|
6582
6614
|
threadId,
|
|
6583
6615
|
commentId,
|
|
6584
|
-
body
|
|
6616
|
+
body,
|
|
6617
|
+
attachmentIds
|
|
6585
6618
|
}) {
|
|
6586
6619
|
const comment = await fetchCommentsJson(
|
|
6587
6620
|
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
@@ -6593,7 +6626,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6593
6626
|
"Content-Type": "application/json"
|
|
6594
6627
|
},
|
|
6595
6628
|
body: JSON.stringify({
|
|
6596
|
-
body
|
|
6629
|
+
body,
|
|
6630
|
+
attachmentIds
|
|
6597
6631
|
})
|
|
6598
6632
|
}
|
|
6599
6633
|
);
|
|
@@ -6645,6 +6679,126 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6645
6679
|
}
|
|
6646
6680
|
);
|
|
6647
6681
|
}
|
|
6682
|
+
function prepareAttachment(file) {
|
|
6683
|
+
return {
|
|
6684
|
+
type: "localAttachment",
|
|
6685
|
+
status: "idle",
|
|
6686
|
+
id: createCommentAttachmentId(),
|
|
6687
|
+
name: file.name,
|
|
6688
|
+
size: file.size,
|
|
6689
|
+
mimeType: file.type,
|
|
6690
|
+
file
|
|
6691
|
+
};
|
|
6692
|
+
}
|
|
6693
|
+
async function uploadAttachment(attachment, options2 = {}) {
|
|
6694
|
+
const abortSignal = options2.signal;
|
|
6695
|
+
const abortError = abortSignal ? new DOMException(
|
|
6696
|
+
`Upload of attachment ${attachment.id} was aborted.`,
|
|
6697
|
+
"AbortError"
|
|
6698
|
+
) : void 0;
|
|
6699
|
+
if (abortSignal?.aborted) {
|
|
6700
|
+
throw abortError;
|
|
6701
|
+
}
|
|
6702
|
+
if (attachment.size <= ATTACHMENT_PART_SIZE) {
|
|
6703
|
+
return fetchCommentsJson(
|
|
6704
|
+
`/attachments/${encodeURIComponent(attachment.id)}/upload/${encodeURIComponent(attachment.name)}`,
|
|
6705
|
+
{
|
|
6706
|
+
method: "PUT",
|
|
6707
|
+
body: attachment.file,
|
|
6708
|
+
signal: abortSignal
|
|
6709
|
+
}
|
|
6710
|
+
);
|
|
6711
|
+
} else {
|
|
6712
|
+
let uploadId;
|
|
6713
|
+
const uploadedParts = [];
|
|
6714
|
+
try {
|
|
6715
|
+
const createMultiPartUpload = await fetchCommentsJson(
|
|
6716
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(attachment.name)}`,
|
|
6717
|
+
{
|
|
6718
|
+
method: "POST",
|
|
6719
|
+
signal: abortSignal
|
|
6720
|
+
}
|
|
6721
|
+
);
|
|
6722
|
+
uploadId = createMultiPartUpload.uploadId;
|
|
6723
|
+
const parts = splitFileIntoParts(attachment.file);
|
|
6724
|
+
if (abortSignal?.aborted) {
|
|
6725
|
+
throw abortError;
|
|
6726
|
+
}
|
|
6727
|
+
const batches = chunk(parts, ATTACHMENT_PART_BATCH_SIZE);
|
|
6728
|
+
for (const parts2 of batches) {
|
|
6729
|
+
const uploadedPartsPromises = [];
|
|
6730
|
+
for (const { part, partNumber } of parts2) {
|
|
6731
|
+
uploadedPartsPromises.push(
|
|
6732
|
+
fetchCommentsJson(
|
|
6733
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}/${encodeURIComponent(partNumber)}`,
|
|
6734
|
+
{
|
|
6735
|
+
method: "PUT",
|
|
6736
|
+
body: part,
|
|
6737
|
+
signal: abortSignal
|
|
6738
|
+
}
|
|
6739
|
+
)
|
|
6740
|
+
);
|
|
6741
|
+
}
|
|
6742
|
+
uploadedParts.push(...await Promise.all(uploadedPartsPromises));
|
|
6743
|
+
}
|
|
6744
|
+
if (abortSignal?.aborted) {
|
|
6745
|
+
throw abortError;
|
|
6746
|
+
}
|
|
6747
|
+
const sortedUploadedParts = uploadedParts.sort(
|
|
6748
|
+
(a, b) => a.partNumber - b.partNumber
|
|
6749
|
+
);
|
|
6750
|
+
return fetchCommentsJson(
|
|
6751
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}/complete`,
|
|
6752
|
+
{
|
|
6753
|
+
method: "POST",
|
|
6754
|
+
headers: {
|
|
6755
|
+
"Content-Type": "application/json"
|
|
6756
|
+
},
|
|
6757
|
+
body: JSON.stringify({ parts: sortedUploadedParts }),
|
|
6758
|
+
signal: abortSignal
|
|
6759
|
+
}
|
|
6760
|
+
);
|
|
6761
|
+
} catch (error3) {
|
|
6762
|
+
if (uploadId && error3?.name && (error3.name === "AbortError" || error3.name === "TimeoutError")) {
|
|
6763
|
+
await fetchCommentsApi(
|
|
6764
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}`,
|
|
6765
|
+
void 0,
|
|
6766
|
+
{
|
|
6767
|
+
method: "DELETE"
|
|
6768
|
+
}
|
|
6769
|
+
);
|
|
6770
|
+
}
|
|
6771
|
+
throw error3;
|
|
6772
|
+
}
|
|
6773
|
+
}
|
|
6774
|
+
}
|
|
6775
|
+
async function getAttachmentUrls(attachmentIds) {
|
|
6776
|
+
const { urls } = await fetchCommentsJson(
|
|
6777
|
+
"/attachments/presigned-urls",
|
|
6778
|
+
{
|
|
6779
|
+
method: "POST",
|
|
6780
|
+
headers: {
|
|
6781
|
+
"Content-Type": "application/json"
|
|
6782
|
+
},
|
|
6783
|
+
body: JSON.stringify({ attachmentIds })
|
|
6784
|
+
}
|
|
6785
|
+
);
|
|
6786
|
+
return urls;
|
|
6787
|
+
}
|
|
6788
|
+
const batchedGetAttachmentUrls = new Batch(
|
|
6789
|
+
async (batchedAttachmentIds) => {
|
|
6790
|
+
const attachmentIds = batchedAttachmentIds.flat();
|
|
6791
|
+
const attachmentUrls = await getAttachmentUrls(attachmentIds);
|
|
6792
|
+
return attachmentUrls.map(
|
|
6793
|
+
(url) => url ?? new Error("There was an error while getting this attachment's URL")
|
|
6794
|
+
);
|
|
6795
|
+
},
|
|
6796
|
+
{ delay: GET_ATTACHMENT_URLS_BATCH_DELAY }
|
|
6797
|
+
);
|
|
6798
|
+
const attachmentUrlsStore = createBatchStore(batchedGetAttachmentUrls);
|
|
6799
|
+
function getAttachmentUrl(attachmentId) {
|
|
6800
|
+
return batchedGetAttachmentUrls.get(attachmentId);
|
|
6801
|
+
}
|
|
6648
6802
|
async function fetchNotificationsJson(endpoint, options2) {
|
|
6649
6803
|
const authValue = await delegates.authenticate();
|
|
6650
6804
|
const response = await fetchClientApi(
|
|
@@ -6760,7 +6914,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6760
6914
|
// These exist only for our E2E testing app
|
|
6761
6915
|
explicitClose: (event) => managedSocket._privateSendMachineEvent({ type: "EXPLICIT_SOCKET_CLOSE", event }),
|
|
6762
6916
|
rawSend: (data) => managedSocket.send(data)
|
|
6763
|
-
}
|
|
6917
|
+
},
|
|
6918
|
+
attachmentUrlsStore
|
|
6764
6919
|
},
|
|
6765
6920
|
id: config.roomId,
|
|
6766
6921
|
subscribe: makeClassicSubscribeFn(events),
|
|
@@ -6815,6 +6970,9 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6815
6970
|
deleteComment,
|
|
6816
6971
|
addReaction,
|
|
6817
6972
|
removeReaction,
|
|
6973
|
+
prepareAttachment,
|
|
6974
|
+
uploadAttachment,
|
|
6975
|
+
getAttachmentUrl,
|
|
6818
6976
|
// Notifications
|
|
6819
6977
|
getNotificationSettings,
|
|
6820
6978
|
updateNotificationSettings,
|
|
@@ -7095,7 +7253,7 @@ function createClient(options) {
|
|
|
7095
7253
|
() => !resolveUsers,
|
|
7096
7254
|
"Set the resolveUsers option in createClient to specify user info."
|
|
7097
7255
|
);
|
|
7098
|
-
const
|
|
7256
|
+
const batchedResolveUsers = new Batch(
|
|
7099
7257
|
async (batchedUserIds) => {
|
|
7100
7258
|
const userIds = batchedUserIds.flat();
|
|
7101
7259
|
const users = await resolveUsers?.({ userIds });
|
|
@@ -7104,12 +7262,13 @@ function createClient(options) {
|
|
|
7104
7262
|
},
|
|
7105
7263
|
{ delay: RESOLVE_USERS_BATCH_DELAY }
|
|
7106
7264
|
);
|
|
7265
|
+
const usersStore = createBatchStore(batchedResolveUsers);
|
|
7107
7266
|
const resolveRoomsInfo = clientOptions.resolveRoomsInfo;
|
|
7108
7267
|
const warnIfNoResolveRoomsInfo = createDevelopmentWarning(
|
|
7109
7268
|
() => !resolveRoomsInfo,
|
|
7110
7269
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
7111
7270
|
);
|
|
7112
|
-
const
|
|
7271
|
+
const batchedResolveRoomsInfo = new Batch(
|
|
7113
7272
|
async (batchedRoomIds) => {
|
|
7114
7273
|
const roomIds = batchedRoomIds.flat();
|
|
7115
7274
|
const roomsInfo = await resolveRoomsInfo?.({ roomIds });
|
|
@@ -7118,6 +7277,7 @@ function createClient(options) {
|
|
|
7118
7277
|
},
|
|
7119
7278
|
{ delay: RESOLVE_ROOMS_INFO_BATCH_DELAY }
|
|
7120
7279
|
);
|
|
7280
|
+
const roomsInfoStore = createBatchStore(batchedResolveRoomsInfo);
|
|
7121
7281
|
return Object.defineProperty(
|
|
7122
7282
|
{
|
|
7123
7283
|
enterRoom,
|
|
@@ -8020,6 +8180,7 @@ export {
|
|
|
8020
8180
|
assert,
|
|
8021
8181
|
assertNever,
|
|
8022
8182
|
b64decode,
|
|
8183
|
+
chunk,
|
|
8023
8184
|
cloneLson,
|
|
8024
8185
|
compactObject,
|
|
8025
8186
|
fancy_console_exports as console,
|