@liveblocks/node 3.23.0-file3 → 3.23.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.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { Permission, Json, DFMD, FeedCreateMetadata, RoomPermissions, RoomAccesses, OptionalTupleUnless, BaseUserMeta, DU, PartialUnless, UpdateRoomAccesses, DE, JsonObject, PlainLsonObject, ToJson, DS, QueryMetadata, DTM, ThreadVisibility, ThreadData, DCM, UserSubscriptionData, CommentData, BaseMetadata, CommentBody, Patchable, LiveFile, LiveFileReference, SubscriptionData, CommentUserReaction, InboxNotificationData, UserRoomSubscriptionSettings, RoomSubscriptionSettings, KDAD, DAD, NotificationSettings, PartialNotificationSettings, GroupScopes, GroupData, LiveObject, Awaitable, DFM, Feed, FeedUpdateMetadata, FeedMessage, NotificationChannel } from '@liveblocks/core';
2
- export { CommentBody, CommentBodyBlockElement, CommentBodyElement, CommentBodyInlineElement, CommentBodyLink, CommentBodyLinkElementArgs, CommentBodyMention, CommentBodyMentionElementArgs, CommentBodyParagraph, CommentBodyParagraphElementArgs, CommentBodyText, CommentBodyTextElementArgs, CommentData, CommentUserReaction, IUserInfo, Json, JsonArray, JsonObject, JsonScalar, LiveFile, LiveFileData, LiveList, LiveMap, LiveObject, LiveStructure, Lson, LsonObject, PlainLsonObject, ResolveUsersArgs, RoomAccesses, RoomPermissions, StringifyCommentBodyElements, StringifyCommentBodyOptions, ThreadData, User, getMentionsFromCommentBody, isNotificationChannelEnabled, stringifyCommentBody } from '@liveblocks/core';
1
+ import { Permission, Json, DFMD, FeedCreateMetadata, RoomPermissions, RoomAccesses, OptionalTupleUnless, BaseUserMeta, DU, PartialUnless, UpdateRoomAccesses, DE, JsonObject, PlainLsonObject, ToJson, DS, QueryMetadata, DTM, ThreadVisibility, ThreadData, DCM, UserSubscriptionData, CommentData, BaseMetadata, CommentBody, Patchable, CommentAttachment, LiveFile, LiveFileReference, SubscriptionData, CommentUserReaction, InboxNotificationData, UserRoomSubscriptionSettings, RoomSubscriptionSettings, KDAD, DAD, NotificationSettings, PartialNotificationSettings, GroupScopes, GroupData, LiveObject, Awaitable, DFM, Feed, FeedUpdateMetadata, FeedMessage, NotificationChannel } from '@liveblocks/core';
2
+ export { CommentAttachment, CommentBody, CommentBodyBlockElement, CommentBodyElement, CommentBodyInlineElement, CommentBodyLink, CommentBodyLinkElementArgs, CommentBodyMention, CommentBodyMentionElementArgs, CommentBodyParagraph, CommentBodyParagraphElementArgs, CommentBodyText, CommentBodyTextElementArgs, CommentData, CommentUserReaction, IUserInfo, Json, JsonArray, JsonObject, JsonScalar, LiveFile, LiveFileData, LiveList, LiveMap, LiveObject, LiveStructure, Lson, LsonObject, PlainLsonObject, ResolveUsersArgs, RoomAccesses, RoomPermissions, StringifyCommentBodyElements, StringifyCommentBodyOptions, ThreadData, User, getMentionsFromCommentBody, isNotificationChannelEnabled, stringifyCommentBody } from '@liveblocks/core';
3
3
  import { IncomingHttpHeaders } from 'http';
4
4
 
5
5
  /**
@@ -114,6 +114,7 @@ type CreateThreadOptions<TM extends BaseMetadata, CM extends BaseMetadata> = {
114
114
  userId: string;
115
115
  createdAt?: Date;
116
116
  body: CommentBody;
117
+ attachmentIds?: string[];
117
118
  } & PartialUnless<CM, {
118
119
  metadata: CM;
119
120
  }>;
@@ -128,6 +129,7 @@ type CreateCommentOptions<CM extends BaseMetadata> = {
128
129
  userId: string;
129
130
  createdAt?: Date;
130
131
  body: CommentBody;
132
+ attachmentIds?: string[];
131
133
  } & PartialUnless<CM, {
132
134
  metadata: CM;
133
135
  }>;
@@ -930,6 +932,7 @@ declare class Liveblocks {
930
932
  * @param params.data.userId The user ID of the user who is set to create the comment.
931
933
  * @param params.data.createdAt (optional) The date the comment is set to be created.
932
934
  * @param params.data.body The body of the comment.
935
+ * @param params.data.attachmentIds (optional) The attachment IDs to add to the comment.
933
936
  * @param params.data.metadata (optional) The metadata for the comment.
934
937
  * @param options.signal (optional) An abort signal to cancel the request.
935
938
  * @returns The created comment.
@@ -941,6 +944,7 @@ declare class Liveblocks {
941
944
  * @param params.threadId The thread ID to edit the comment in.
942
945
  * @param params.commentId The comment ID to edit.
943
946
  * @param params.data.body The body of the comment.
947
+ * @param params.data.attachmentIds (optional) The IDs of every attachment that should remain on the comment.
944
948
  * @param params.data.metadata (optional) The metadata for the comment. Value must be a string, boolean or number. Use null to delete a key.
945
949
  * @param params.data.editedAt (optional) The date the comment was edited.
946
950
  * @param options.signal (optional) An abort signal to cancel the request.
@@ -952,6 +956,7 @@ declare class Liveblocks {
952
956
  commentId: string;
953
957
  data: {
954
958
  body: CommentBody;
959
+ attachmentIds?: string[];
955
960
  metadata?: Patchable<CM>;
956
961
  editedAt?: Date;
957
962
  };
@@ -980,6 +985,20 @@ declare class Liveblocks {
980
985
  roomId: string;
981
986
  attachmentId: string;
982
987
  }, options?: RequestOptions): Promise<AttachmentWithUrl>;
988
+ /**
989
+ * Uploads an attachment that can be added to a comment.
990
+ *
991
+ * @param params.roomId The room ID to upload the attachment to.
992
+ * @param params.userId The user ID of the user uploading the attachment.
993
+ * @param params.file The file to upload.
994
+ * @param options.signal (optional) An abort signal to cancel the upload.
995
+ * @returns The uploaded attachment.
996
+ */
997
+ uploadAttachment(params: {
998
+ roomId: string;
999
+ userId: string;
1000
+ file: File;
1001
+ }, options?: RequestOptions): Promise<CommentAttachment>;
983
1002
  uploadFile(params: {
984
1003
  roomId: string;
985
1004
  file: File;
@@ -996,6 +1015,7 @@ declare class Liveblocks {
996
1015
  * @param params.thread.comment.userId The user ID of the user who created the comment.
997
1016
  * @param params.thread.comment.createdAt (optional) The date the comment was created.
998
1017
  * @param params.thread.comment.body The body of the comment.
1018
+ * @param params.thread.comment.attachmentIds (optional) The attachment IDs to add to the comment.
999
1019
  * @param params.thread.comment.metadata (optional) The metadata for the comment.
1000
1020
  * @param options.signal (optional) An abort signal to cancel the request.
1001
1021
  * @returns The created thread. The thread will be created with the specified comment as its first comment.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Permission, Json, DFMD, FeedCreateMetadata, RoomPermissions, RoomAccesses, OptionalTupleUnless, BaseUserMeta, DU, PartialUnless, UpdateRoomAccesses, DE, JsonObject, PlainLsonObject, ToJson, DS, QueryMetadata, DTM, ThreadVisibility, ThreadData, DCM, UserSubscriptionData, CommentData, BaseMetadata, CommentBody, Patchable, LiveFile, LiveFileReference, SubscriptionData, CommentUserReaction, InboxNotificationData, UserRoomSubscriptionSettings, RoomSubscriptionSettings, KDAD, DAD, NotificationSettings, PartialNotificationSettings, GroupScopes, GroupData, LiveObject, Awaitable, DFM, Feed, FeedUpdateMetadata, FeedMessage, NotificationChannel } from '@liveblocks/core';
2
- export { CommentBody, CommentBodyBlockElement, CommentBodyElement, CommentBodyInlineElement, CommentBodyLink, CommentBodyLinkElementArgs, CommentBodyMention, CommentBodyMentionElementArgs, CommentBodyParagraph, CommentBodyParagraphElementArgs, CommentBodyText, CommentBodyTextElementArgs, CommentData, CommentUserReaction, IUserInfo, Json, JsonArray, JsonObject, JsonScalar, LiveFile, LiveFileData, LiveList, LiveMap, LiveObject, LiveStructure, Lson, LsonObject, PlainLsonObject, ResolveUsersArgs, RoomAccesses, RoomPermissions, StringifyCommentBodyElements, StringifyCommentBodyOptions, ThreadData, User, getMentionsFromCommentBody, isNotificationChannelEnabled, stringifyCommentBody } from '@liveblocks/core';
1
+ import { Permission, Json, DFMD, FeedCreateMetadata, RoomPermissions, RoomAccesses, OptionalTupleUnless, BaseUserMeta, DU, PartialUnless, UpdateRoomAccesses, DE, JsonObject, PlainLsonObject, ToJson, DS, QueryMetadata, DTM, ThreadVisibility, ThreadData, DCM, UserSubscriptionData, CommentData, BaseMetadata, CommentBody, Patchable, CommentAttachment, LiveFile, LiveFileReference, SubscriptionData, CommentUserReaction, InboxNotificationData, UserRoomSubscriptionSettings, RoomSubscriptionSettings, KDAD, DAD, NotificationSettings, PartialNotificationSettings, GroupScopes, GroupData, LiveObject, Awaitable, DFM, Feed, FeedUpdateMetadata, FeedMessage, NotificationChannel } from '@liveblocks/core';
2
+ export { CommentAttachment, CommentBody, CommentBodyBlockElement, CommentBodyElement, CommentBodyInlineElement, CommentBodyLink, CommentBodyLinkElementArgs, CommentBodyMention, CommentBodyMentionElementArgs, CommentBodyParagraph, CommentBodyParagraphElementArgs, CommentBodyText, CommentBodyTextElementArgs, CommentData, CommentUserReaction, IUserInfo, Json, JsonArray, JsonObject, JsonScalar, LiveFile, LiveFileData, LiveList, LiveMap, LiveObject, LiveStructure, Lson, LsonObject, PlainLsonObject, ResolveUsersArgs, RoomAccesses, RoomPermissions, StringifyCommentBodyElements, StringifyCommentBodyOptions, ThreadData, User, getMentionsFromCommentBody, isNotificationChannelEnabled, stringifyCommentBody } from '@liveblocks/core';
3
3
  import { IncomingHttpHeaders } from 'http';
4
4
 
5
5
  /**
@@ -114,6 +114,7 @@ type CreateThreadOptions<TM extends BaseMetadata, CM extends BaseMetadata> = {
114
114
  userId: string;
115
115
  createdAt?: Date;
116
116
  body: CommentBody;
117
+ attachmentIds?: string[];
117
118
  } & PartialUnless<CM, {
118
119
  metadata: CM;
119
120
  }>;
@@ -128,6 +129,7 @@ type CreateCommentOptions<CM extends BaseMetadata> = {
128
129
  userId: string;
129
130
  createdAt?: Date;
130
131
  body: CommentBody;
132
+ attachmentIds?: string[];
131
133
  } & PartialUnless<CM, {
132
134
  metadata: CM;
133
135
  }>;
@@ -930,6 +932,7 @@ declare class Liveblocks {
930
932
  * @param params.data.userId The user ID of the user who is set to create the comment.
931
933
  * @param params.data.createdAt (optional) The date the comment is set to be created.
932
934
  * @param params.data.body The body of the comment.
935
+ * @param params.data.attachmentIds (optional) The attachment IDs to add to the comment.
933
936
  * @param params.data.metadata (optional) The metadata for the comment.
934
937
  * @param options.signal (optional) An abort signal to cancel the request.
935
938
  * @returns The created comment.
@@ -941,6 +944,7 @@ declare class Liveblocks {
941
944
  * @param params.threadId The thread ID to edit the comment in.
942
945
  * @param params.commentId The comment ID to edit.
943
946
  * @param params.data.body The body of the comment.
947
+ * @param params.data.attachmentIds (optional) The IDs of every attachment that should remain on the comment.
944
948
  * @param params.data.metadata (optional) The metadata for the comment. Value must be a string, boolean or number. Use null to delete a key.
945
949
  * @param params.data.editedAt (optional) The date the comment was edited.
946
950
  * @param options.signal (optional) An abort signal to cancel the request.
@@ -952,6 +956,7 @@ declare class Liveblocks {
952
956
  commentId: string;
953
957
  data: {
954
958
  body: CommentBody;
959
+ attachmentIds?: string[];
955
960
  metadata?: Patchable<CM>;
956
961
  editedAt?: Date;
957
962
  };
@@ -980,6 +985,20 @@ declare class Liveblocks {
980
985
  roomId: string;
981
986
  attachmentId: string;
982
987
  }, options?: RequestOptions): Promise<AttachmentWithUrl>;
988
+ /**
989
+ * Uploads an attachment that can be added to a comment.
990
+ *
991
+ * @param params.roomId The room ID to upload the attachment to.
992
+ * @param params.userId The user ID of the user uploading the attachment.
993
+ * @param params.file The file to upload.
994
+ * @param options.signal (optional) An abort signal to cancel the upload.
995
+ * @returns The uploaded attachment.
996
+ */
997
+ uploadAttachment(params: {
998
+ roomId: string;
999
+ userId: string;
1000
+ file: File;
1001
+ }, options?: RequestOptions): Promise<CommentAttachment>;
983
1002
  uploadFile(params: {
984
1003
  roomId: string;
985
1004
  file: File;
@@ -996,6 +1015,7 @@ declare class Liveblocks {
996
1015
  * @param params.thread.comment.userId The user ID of the user who created the comment.
997
1016
  * @param params.thread.comment.createdAt (optional) The date the comment was created.
998
1017
  * @param params.thread.comment.body The body of the comment.
1018
+ * @param params.thread.comment.attachmentIds (optional) The attachment IDs to add to the comment.
999
1019
  * @param params.thread.comment.metadata (optional) The metadata for the comment.
1000
1020
  * @param options.signal (optional) An abort signal to cancel the request.
1001
1021
  * @returns The created thread. The thread will be created with the specified comment as its first comment.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { detectDupes } from "@liveblocks/core";
3
3
 
4
4
  // src/version.ts
5
5
  var PKG_NAME = "@liveblocks/node";
6
- var PKG_VERSION = "3.23.0-file3";
6
+ var PKG_VERSION = "3.23.0";
7
7
  var PKG_FORMAT = "esm";
8
8
 
9
9
  // src/client.ts
@@ -19,6 +19,7 @@ import {
19
19
  convertToSubscriptionData,
20
20
  convertToThreadData,
21
21
  convertToUserSubscriptionData,
22
+ createCommentAttachmentId,
22
23
  createManagedPool,
23
24
  createNotificationSettings,
24
25
  createStorageFileId,
@@ -294,9 +295,9 @@ var Session = class {
294
295
  };
295
296
 
296
297
  // src/client.ts
297
- var STORAGE_FILE_PART_SIZE = 5 * 1024 * 1024;
298
- var STORAGE_FILE_RETRY_ATTEMPTS = 10;
299
- var STORAGE_FILE_RETRY_DELAYS = [
298
+ var ROOM_FILE_PART_SIZE = 5 * 1024 * 1024;
299
+ var ROOM_FILE_RETRY_ATTEMPTS = 10;
300
+ var ROOM_FILE_RETRY_DELAYS = [
300
301
  2e3,
301
302
  2e3,
302
303
  2e3,
@@ -308,10 +309,11 @@ var STORAGE_FILE_RETRY_DELAYS = [
308
309
  2e3,
309
310
  2e3
310
311
  ];
311
- async function uploadStorageFile({
312
+ async function uploadRoomFile({
312
313
  file,
313
314
  signal,
314
315
  abortErrorMessage,
316
+ retryMultipartCompletion,
315
317
  uploadSingle,
316
318
  createMultipartUpload,
317
319
  uploadMultipartPart,
@@ -328,36 +330,77 @@ async function uploadStorageFile({
328
330
  }
329
331
  return err instanceof LiveblocksError && err.status >= 400 && err.status < 500;
330
332
  };
331
- if (file.size <= STORAGE_FILE_PART_SIZE) {
333
+ if (file.size <= ROOM_FILE_PART_SIZE) {
332
334
  return autoRetry(
333
335
  uploadSingle,
334
- STORAGE_FILE_RETRY_ATTEMPTS,
335
- STORAGE_FILE_RETRY_DELAYS,
336
+ ROOM_FILE_RETRY_ATTEMPTS,
337
+ ROOM_FILE_RETRY_DELAYS,
336
338
  handleRetryError
337
339
  );
338
340
  }
339
341
  let uploadId;
340
342
  const uploadedParts = [];
341
- const multipartUpload = await createMultipartUpload();
343
+ const multipartUpload = await autoRetry(
344
+ createMultipartUpload,
345
+ ROOM_FILE_RETRY_ATTEMPTS,
346
+ ROOM_FILE_RETRY_DELAYS,
347
+ handleRetryError
348
+ );
349
+ const partUploadController = new AbortController();
350
+ const partUploadSignal = partUploadController.signal;
351
+ const abortPartUploads = (reason) => {
352
+ partUploadController.abort(reason);
353
+ };
354
+ const handleExternalAbort = () => abortPartUploads();
355
+ if (signal?.aborted) {
356
+ handleExternalAbort();
357
+ } else {
358
+ signal?.addEventListener("abort", handleExternalAbort, { once: true });
359
+ }
342
360
  try {
343
361
  uploadId = multipartUpload.uploadId;
344
362
  if (signal?.aborted) {
345
363
  throw abortError;
346
364
  }
347
- const batches = chunk(splitStorageFileIntoParts(file), 5);
365
+ const batches = chunk(splitRoomFileIntoParts(file), 5);
348
366
  for (const parts of batches) {
349
- const uploadedPartPromises = [];
367
+ const firstPartUploadFailure = {};
368
+ const partUploads$ = [];
350
369
  for (const { part, partNumber } of parts) {
351
- uploadedPartPromises.push(
370
+ partUploads$.push(
352
371
  autoRetry(
353
- () => uploadMultipartPart(multipartUpload.uploadId, partNumber, part),
354
- STORAGE_FILE_RETRY_ATTEMPTS,
355
- STORAGE_FILE_RETRY_DELAYS,
356
- handleRetryError
357
- )
372
+ () => uploadMultipartPart(
373
+ multipartUpload.uploadId,
374
+ partNumber,
375
+ part,
376
+ partUploadSignal
377
+ ),
378
+ ROOM_FILE_RETRY_ATTEMPTS,
379
+ ROOM_FILE_RETRY_DELAYS,
380
+ (error) => {
381
+ if (signal?.aborted) {
382
+ throw abortError;
383
+ }
384
+ return partUploadSignal.aborted || handleRetryError(error);
385
+ }
386
+ ).catch((error) => {
387
+ if (firstPartUploadFailure.value === void 0) {
388
+ firstPartUploadFailure.value = { error };
389
+ abortPartUploads(error);
390
+ }
391
+ throw error;
392
+ })
358
393
  );
359
394
  }
360
- uploadedParts.push(...await Promise.all(uploadedPartPromises));
395
+ const settledPartUploads = await Promise.allSettled(partUploads$);
396
+ if (firstPartUploadFailure.value !== void 0) {
397
+ throw firstPartUploadFailure.value.error;
398
+ }
399
+ for (const settledPartUpload of settledPartUploads) {
400
+ if (settledPartUpload.status === "fulfilled") {
401
+ uploadedParts.push(settledPartUpload.value);
402
+ }
403
+ }
361
404
  }
362
405
  if (signal?.aborted) {
363
406
  throw abortError;
@@ -365,12 +408,12 @@ async function uploadStorageFile({
365
408
  const sortedParts = uploadedParts.sort(
366
409
  (a, b) => a.partNumber - b.partNumber
367
410
  );
368
- return autoRetry(
411
+ return retryMultipartCompletion ? autoRetry(
369
412
  () => completeMultipartUpload(multipartUpload.uploadId, sortedParts),
370
- STORAGE_FILE_RETRY_ATTEMPTS,
371
- STORAGE_FILE_RETRY_DELAYS,
413
+ ROOM_FILE_RETRY_ATTEMPTS,
414
+ ROOM_FILE_RETRY_DELAYS,
372
415
  handleRetryError
373
- );
416
+ ) : completeMultipartUpload(uploadId, sortedParts);
374
417
  } catch (err) {
375
418
  if (uploadId) {
376
419
  try {
@@ -379,13 +422,15 @@ async function uploadStorageFile({
379
422
  }
380
423
  }
381
424
  throw err;
425
+ } finally {
426
+ signal?.removeEventListener("abort", handleExternalAbort);
382
427
  }
383
428
  }
384
- function splitStorageFileIntoParts(file) {
429
+ function splitRoomFileIntoParts(file) {
385
430
  const parts = [];
386
431
  let start = 0;
387
432
  while (start < file.size) {
388
- const end = Math.min(start + STORAGE_FILE_PART_SIZE, file.size);
433
+ const end = Math.min(start + ROOM_FILE_PART_SIZE, file.size);
389
434
  parts.push({
390
435
  partNumber: parts.length + 1,
391
436
  part: file.slice(start, end)
@@ -1309,6 +1354,7 @@ var Liveblocks = class {
1309
1354
  * @param params.data.userId The user ID of the user who is set to create the comment.
1310
1355
  * @param params.data.createdAt (optional) The date the comment is set to be created.
1311
1356
  * @param params.data.body The body of the comment.
1357
+ * @param params.data.attachmentIds (optional) The attachment IDs to add to the comment.
1312
1358
  * @param params.data.metadata (optional) The metadata for the comment.
1313
1359
  * @param options.signal (optional) An abort signal to cancel the request.
1314
1360
  * @returns The created comment.
@@ -1334,6 +1380,7 @@ var Liveblocks = class {
1334
1380
  * @param params.threadId The thread ID to edit the comment in.
1335
1381
  * @param params.commentId The comment ID to edit.
1336
1382
  * @param params.data.body The body of the comment.
1383
+ * @param params.data.attachmentIds (optional) The IDs of every attachment that should remain on the comment.
1337
1384
  * @param params.data.metadata (optional) The metadata for the comment. Value must be a string, boolean or number. Use null to delete a key.
1338
1385
  * @param params.data.editedAt (optional) The date the comment was edited.
1339
1386
  * @param options.signal (optional) An abort signal to cancel the request.
@@ -1346,6 +1393,7 @@ var Liveblocks = class {
1346
1393
  {
1347
1394
  body: data.body,
1348
1395
  editedAt: data.editedAt?.toISOString(),
1396
+ attachmentIds: data.attachmentIds,
1349
1397
  metadata: data.metadata
1350
1398
  },
1351
1399
  options
@@ -1393,13 +1441,77 @@ var Liveblocks = class {
1393
1441
  }
1394
1442
  return await res.json();
1395
1443
  }
1444
+ /**
1445
+ * Uploads an attachment that can be added to a comment.
1446
+ *
1447
+ * @param params.roomId The room ID to upload the attachment to.
1448
+ * @param params.userId The user ID of the user uploading the attachment.
1449
+ * @param params.file The file to upload.
1450
+ * @param options.signal (optional) An abort signal to cancel the upload.
1451
+ * @returns The uploaded attachment.
1452
+ */
1453
+ async uploadAttachment(params, options) {
1454
+ const { roomId, userId, file } = params;
1455
+ const attachmentId = createCommentAttachmentId();
1456
+ return await uploadRoomFile({
1457
+ file,
1458
+ signal: options?.signal,
1459
+ abortErrorMessage: `Upload of attachment ${attachmentId} was aborted.`,
1460
+ retryMultipartCompletion: false,
1461
+ uploadSingle: async () => {
1462
+ const res = await this.#putBlob(
1463
+ url2`/v2/rooms/${roomId}/attachments/${attachmentId}/upload/${file.name}`,
1464
+ file,
1465
+ { fileSize: file.size, userId },
1466
+ options
1467
+ );
1468
+ return await this.#readJsonResponse(res);
1469
+ },
1470
+ createMultipartUpload: async () => {
1471
+ const res = await this.#post(
1472
+ url2`/v2/rooms/${roomId}/attachments/${attachmentId}/multipart/${file.name}`,
1473
+ void 0,
1474
+ options,
1475
+ { fileSize: file.size }
1476
+ );
1477
+ return await this.#readJsonResponse(res);
1478
+ },
1479
+ uploadMultipartPart: async (uploadId, partNumber, part, signal) => {
1480
+ const res = await this.#putBlob(
1481
+ url2`/v2/rooms/${roomId}/attachments/${attachmentId}/multipart/${uploadId}/${String(partNumber)}`,
1482
+ part,
1483
+ void 0,
1484
+ { signal }
1485
+ );
1486
+ return await this.#readJsonResponse(res);
1487
+ },
1488
+ completeMultipartUpload: async (uploadId, parts) => {
1489
+ const res = await this.#post(
1490
+ url2`/v2/rooms/${roomId}/attachments/${attachmentId}/multipart/${uploadId}/complete`,
1491
+ { parts },
1492
+ options,
1493
+ { userId }
1494
+ );
1495
+ return await this.#readJsonResponse(res);
1496
+ },
1497
+ abortMultipartUpload: async (uploadId) => {
1498
+ const res = await this.#delete(
1499
+ url2`/v2/rooms/${roomId}/attachments/${attachmentId}/multipart/${uploadId}`
1500
+ );
1501
+ if (!res.ok) {
1502
+ throw await LiveblocksError.from(res);
1503
+ }
1504
+ }
1505
+ });
1506
+ }
1396
1507
  async uploadFile(params, options) {
1397
1508
  const { roomId, file } = params;
1398
1509
  const fileId = createStorageFileId();
1399
- const fileData = await uploadStorageFile({
1510
+ const fileData = await uploadRoomFile({
1400
1511
  file,
1401
1512
  signal: options?.signal,
1402
1513
  abortErrorMessage: `Upload of file ${fileId} was aborted.`,
1514
+ retryMultipartCompletion: true,
1403
1515
  uploadSingle: async () => {
1404
1516
  const res = await this.#putBlob(
1405
1517
  url2`/v2/rooms/${roomId}/storage/files/${fileId}/upload/${file.name}`,
@@ -1418,12 +1530,12 @@ var Liveblocks = class {
1418
1530
  );
1419
1531
  return await this.#readJsonResponse(res);
1420
1532
  },
1421
- uploadMultipartPart: async (uploadId, partNumber, part) => {
1533
+ uploadMultipartPart: async (uploadId, partNumber, part, signal) => {
1422
1534
  const res = await this.#putBlob(
1423
1535
  url2`/v2/rooms/${roomId}/storage/files/${fileId}/multipart/${uploadId}/${String(partNumber)}`,
1424
1536
  part,
1425
1537
  void 0,
1426
- options
1538
+ { signal }
1427
1539
  );
1428
1540
  return await this.#readJsonResponse(res);
1429
1541
  },
@@ -1468,6 +1580,7 @@ var Liveblocks = class {
1468
1580
  * @param params.thread.comment.userId The user ID of the user who created the comment.
1469
1581
  * @param params.thread.comment.createdAt (optional) The date the comment was created.
1470
1582
  * @param params.thread.comment.body The body of the comment.
1583
+ * @param params.thread.comment.attachmentIds (optional) The attachment IDs to add to the comment.
1471
1584
  * @param params.thread.comment.metadata (optional) The metadata for the comment.
1472
1585
  * @param options.signal (optional) An abort signal to cancel the request.
1473
1586
  * @returns The created thread. The thread will be created with the specified comment as its first comment.