@liveblocks/node 3.23.0-file4 → 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.cjs CHANGED
@@ -3,7 +3,7 @@ var _core = require('@liveblocks/core');
3
3
 
4
4
  // src/version.ts
5
5
  var PKG_NAME = "@liveblocks/node";
6
- var PKG_VERSION = "3.23.0-file4";
6
+ var PKG_VERSION = "3.23.0";
7
7
  var PKG_FORMAT = "cjs";
8
8
 
9
9
  // src/client.ts
@@ -34,6 +34,7 @@ var PKG_FORMAT = "cjs";
34
34
 
35
35
 
36
36
 
37
+
37
38
 
38
39
 
39
40
  // src/lib/itertools.ts
@@ -294,9 +295,9 @@ var Session = (_class = class {
294
295
  }, _class);
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,11 +330,11 @@ 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 _core.autoRetry.call(void 0,
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
  }
@@ -340,8 +342,8 @@ async function uploadStorageFile({
340
342
  const uploadedParts = [];
341
343
  const multipartUpload = await _core.autoRetry.call(void 0,
342
344
  createMultipartUpload,
343
- STORAGE_FILE_RETRY_ATTEMPTS,
344
- STORAGE_FILE_RETRY_DELAYS,
345
+ ROOM_FILE_RETRY_ATTEMPTS,
346
+ ROOM_FILE_RETRY_DELAYS,
345
347
  handleRetryError
346
348
  );
347
349
  const partUploadController = new AbortController();
@@ -360,7 +362,7 @@ async function uploadStorageFile({
360
362
  if (_optionalChain([signal, 'optionalAccess', _7 => _7.aborted])) {
361
363
  throw abortError;
362
364
  }
363
- const batches = _core.chunk.call(void 0, splitStorageFileIntoParts(file), 5);
365
+ const batches = _core.chunk.call(void 0, splitRoomFileIntoParts(file), 5);
364
366
  for (const parts of batches) {
365
367
  const firstPartUploadFailure = {};
366
368
  const partUploads$ = [];
@@ -373,8 +375,8 @@ async function uploadStorageFile({
373
375
  part,
374
376
  partUploadSignal
375
377
  ),
376
- STORAGE_FILE_RETRY_ATTEMPTS,
377
- STORAGE_FILE_RETRY_DELAYS,
378
+ ROOM_FILE_RETRY_ATTEMPTS,
379
+ ROOM_FILE_RETRY_DELAYS,
378
380
  (error) => {
379
381
  if (_optionalChain([signal, 'optionalAccess', _8 => _8.aborted])) {
380
382
  throw abortError;
@@ -406,12 +408,12 @@ async function uploadStorageFile({
406
408
  const sortedParts = uploadedParts.sort(
407
409
  (a, b) => a.partNumber - b.partNumber
408
410
  );
409
- return _core.autoRetry.call(void 0,
411
+ return retryMultipartCompletion ? _core.autoRetry.call(void 0,
410
412
  () => completeMultipartUpload(multipartUpload.uploadId, sortedParts),
411
- STORAGE_FILE_RETRY_ATTEMPTS,
412
- STORAGE_FILE_RETRY_DELAYS,
413
+ ROOM_FILE_RETRY_ATTEMPTS,
414
+ ROOM_FILE_RETRY_DELAYS,
413
415
  handleRetryError
414
- );
416
+ ) : completeMultipartUpload(uploadId, sortedParts);
415
417
  } catch (err) {
416
418
  if (uploadId) {
417
419
  try {
@@ -424,11 +426,11 @@ async function uploadStorageFile({
424
426
  _optionalChain([signal, 'optionalAccess', _10 => _10.removeEventListener, 'call', _11 => _11("abort", handleExternalAbort)]);
425
427
  }
426
428
  }
427
- function splitStorageFileIntoParts(file) {
429
+ function splitRoomFileIntoParts(file) {
428
430
  const parts = [];
429
431
  let start = 0;
430
432
  while (start < file.size) {
431
- const end = Math.min(start + STORAGE_FILE_PART_SIZE, file.size);
433
+ const end = Math.min(start + ROOM_FILE_PART_SIZE, file.size);
432
434
  parts.push({
433
435
  partNumber: parts.length + 1,
434
436
  part: file.slice(start, end)
@@ -1352,6 +1354,7 @@ var Liveblocks = class {
1352
1354
  * @param params.data.userId The user ID of the user who is set to create the comment.
1353
1355
  * @param params.data.createdAt (optional) The date the comment is set to be created.
1354
1356
  * @param params.data.body The body of the comment.
1357
+ * @param params.data.attachmentIds (optional) The attachment IDs to add to the comment.
1355
1358
  * @param params.data.metadata (optional) The metadata for the comment.
1356
1359
  * @param options.signal (optional) An abort signal to cancel the request.
1357
1360
  * @returns The created comment.
@@ -1377,6 +1380,7 @@ var Liveblocks = class {
1377
1380
  * @param params.threadId The thread ID to edit the comment in.
1378
1381
  * @param params.commentId The comment ID to edit.
1379
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.
1380
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.
1381
1385
  * @param params.data.editedAt (optional) The date the comment was edited.
1382
1386
  * @param options.signal (optional) An abort signal to cancel the request.
@@ -1389,6 +1393,7 @@ var Liveblocks = class {
1389
1393
  {
1390
1394
  body: data.body,
1391
1395
  editedAt: _optionalChain([data, 'access', _27 => _27.editedAt, 'optionalAccess', _28 => _28.toISOString, 'call', _29 => _29()]),
1396
+ attachmentIds: data.attachmentIds,
1392
1397
  metadata: data.metadata
1393
1398
  },
1394
1399
  options
@@ -1436,13 +1441,77 @@ var Liveblocks = class {
1436
1441
  }
1437
1442
  return await res.json();
1438
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 = _core.createCommentAttachmentId.call(void 0, );
1456
+ return await uploadRoomFile({
1457
+ file,
1458
+ signal: _optionalChain([options, 'optionalAccess', _30 => _30.signal]),
1459
+ abortErrorMessage: `Upload of attachment ${attachmentId} was aborted.`,
1460
+ retryMultipartCompletion: false,
1461
+ uploadSingle: async () => {
1462
+ const res = await this.#putBlob(
1463
+ _core.url`/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
+ _core.url`/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
+ _core.url`/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
+ _core.url`/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
+ _core.url`/v2/rooms/${roomId}/attachments/${attachmentId}/multipart/${uploadId}`
1500
+ );
1501
+ if (!res.ok) {
1502
+ throw await LiveblocksError.from(res);
1503
+ }
1504
+ }
1505
+ });
1506
+ }
1439
1507
  async uploadFile(params, options) {
1440
1508
  const { roomId, file } = params;
1441
1509
  const fileId = _core.createStorageFileId.call(void 0, );
1442
- const fileData = await uploadStorageFile({
1510
+ const fileData = await uploadRoomFile({
1443
1511
  file,
1444
- signal: _optionalChain([options, 'optionalAccess', _30 => _30.signal]),
1512
+ signal: _optionalChain([options, 'optionalAccess', _31 => _31.signal]),
1445
1513
  abortErrorMessage: `Upload of file ${fileId} was aborted.`,
1514
+ retryMultipartCompletion: true,
1446
1515
  uploadSingle: async () => {
1447
1516
  const res = await this.#putBlob(
1448
1517
  _core.url`/v2/rooms/${roomId}/storage/files/${fileId}/upload/${file.name}`,
@@ -1511,6 +1580,7 @@ var Liveblocks = class {
1511
1580
  * @param params.thread.comment.userId The user ID of the user who created the comment.
1512
1581
  * @param params.thread.comment.createdAt (optional) The date the comment was created.
1513
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.
1514
1584
  * @param params.thread.comment.metadata (optional) The metadata for the comment.
1515
1585
  * @param options.signal (optional) An abort signal to cancel the request.
1516
1586
  * @returns The created thread. The thread will be created with the specified comment as its first comment.
@@ -1523,7 +1593,7 @@ var Liveblocks = class {
1523
1593
  ...data,
1524
1594
  comment: {
1525
1595
  ...data.comment,
1526
- createdAt: _optionalChain([data, 'access', _31 => _31.comment, 'access', _32 => _32.createdAt, 'optionalAccess', _33 => _33.toISOString, 'call', _34 => _34()])
1596
+ createdAt: _optionalChain([data, 'access', _32 => _32.comment, 'access', _33 => _33.createdAt, 'optionalAccess', _34 => _34.toISOString, 'call', _35 => _35()])
1527
1597
  }
1528
1598
  },
1529
1599
  options
@@ -1646,7 +1716,7 @@ var Liveblocks = class {
1646
1716
  _core.url`/v2/rooms/${roomId}/threads/${threadId}/metadata`,
1647
1717
  {
1648
1718
  ...data,
1649
- updatedAt: _optionalChain([data, 'access', _35 => _35.updatedAt, 'optionalAccess', _36 => _36.toISOString, 'call', _37 => _37()])
1719
+ updatedAt: _optionalChain([data, 'access', _36 => _36.updatedAt, 'optionalAccess', _37 => _37.toISOString, 'call', _38 => _38()])
1650
1720
  },
1651
1721
  options
1652
1722
  );
@@ -1672,7 +1742,7 @@ var Liveblocks = class {
1672
1742
  _core.url`/v2/rooms/${roomId}/threads/${threadId}/comments/${commentId}/metadata`,
1673
1743
  {
1674
1744
  ...data,
1675
- updatedAt: _optionalChain([data, 'access', _38 => _38.updatedAt, 'optionalAccess', _39 => _39.toISOString, 'call', _40 => _40()])
1745
+ updatedAt: _optionalChain([data, 'access', _39 => _39.updatedAt, 'optionalAccess', _40 => _40.toISOString, 'call', _41 => _41()])
1676
1746
  },
1677
1747
  options
1678
1748
  );
@@ -1698,7 +1768,7 @@ var Liveblocks = class {
1698
1768
  _core.url`/v2/rooms/${roomId}/threads/${threadId}/comments/${commentId}/add-reaction`,
1699
1769
  {
1700
1770
  ...data,
1701
- createdAt: _optionalChain([data, 'access', _41 => _41.createdAt, 'optionalAccess', _42 => _42.toISOString, 'call', _43 => _43()])
1771
+ createdAt: _optionalChain([data, 'access', _42 => _42.createdAt, 'optionalAccess', _43 => _43.toISOString, 'call', _44 => _44()])
1702
1772
  },
1703
1773
  options
1704
1774
  );
@@ -1724,7 +1794,7 @@ var Liveblocks = class {
1724
1794
  _core.url`/v2/rooms/${roomId}/threads/${threadId}/comments/${params.commentId}/remove-reaction`,
1725
1795
  {
1726
1796
  ...data,
1727
- removedAt: _optionalChain([data, 'access', _44 => _44.removedAt, 'optionalAccess', _45 => _45.toISOString, 'call', _46 => _46()])
1797
+ removedAt: _optionalChain([data, 'access', _45 => _45.removedAt, 'optionalAccess', _46 => _46.toISOString, 'call', _47 => _47()])
1728
1798
  },
1729
1799
  options
1730
1800
  );
@@ -1805,7 +1875,7 @@ var Liveblocks = class {
1805
1875
  */
1806
1876
  async *iterInboxNotifications(criteria, options) {
1807
1877
  const { signal } = _nullishCoalesce(options, () => ( {}));
1808
- const pageSize = _core.checkBounds.call(void 0, "pageSize", _nullishCoalesce(_optionalChain([options, 'optionalAccess', _47 => _47.pageSize]), () => ( 50)), 10);
1878
+ const pageSize = _core.checkBounds.call(void 0, "pageSize", _nullishCoalesce(_optionalChain([options, 'optionalAccess', _48 => _48.pageSize]), () => ( 50)), 10);
1809
1879
  let cursor = void 0;
1810
1880
  while (true) {
1811
1881
  const { nextCursor, data } = await this.getInboxNotifications(
@@ -2152,7 +2222,7 @@ var Liveblocks = class {
2152
2222
  async getGroups(params, options) {
2153
2223
  const res = await this.#get(
2154
2224
  _core.url`/v2/groups`,
2155
- { startingAfter: _optionalChain([params, 'optionalAccess', _48 => _48.startingAfter]), limit: _optionalChain([params, 'optionalAccess', _49 => _49.limit]) },
2225
+ { startingAfter: _optionalChain([params, 'optionalAccess', _49 => _49.startingAfter]), limit: _optionalChain([params, 'optionalAccess', _50 => _50.limit]) },
2156
2226
  options
2157
2227
  );
2158
2228
  if (!res.ok) {
@@ -2214,7 +2284,7 @@ var Liveblocks = class {
2214
2284
  async massMutateStorage(criteria, callback, massOptions) {
2215
2285
  const concurrency = _core.checkBounds.call(void 0,
2216
2286
  "concurrency",
2217
- _nullishCoalesce(_optionalChain([massOptions, 'optionalAccess', _50 => _50.concurrency]), () => ( 8)),
2287
+ _nullishCoalesce(_optionalChain([massOptions, 'optionalAccess', _51 => _51.concurrency]), () => ( 8)),
2218
2288
  1,
2219
2289
  20
2220
2290
  );
@@ -2230,7 +2300,7 @@ var Liveblocks = class {
2230
2300
  }
2231
2301
  async #_mutateOneRoom(roomId, room, callback, options) {
2232
2302
  const debounceInterval = 200;
2233
- const { signal, abort } = _core.makeAbortController.call(void 0, _optionalChain([options, 'optionalAccess', _51 => _51.signal]));
2303
+ const { signal, abort } = _core.makeAbortController.call(void 0, _optionalChain([options, 'optionalAccess', _52 => _52.signal]));
2234
2304
  let opsBuffer = [];
2235
2305
  let outstandingFlush$ = void 0;
2236
2306
  let lastFlush = performance.now();
@@ -2296,7 +2366,7 @@ var Liveblocks = class {
2296
2366
  const res = await this.#post(
2297
2367
  _core.url`/v2/rooms/${roomId}/send-message`,
2298
2368
  { messages },
2299
- { signal: _optionalChain([options, 'optionalAccess', _52 => _52.signal]) }
2369
+ { signal: _optionalChain([options, 'optionalAccess', _53 => _53.signal]) }
2300
2370
  );
2301
2371
  if (!res.ok) {
2302
2372
  throw await LiveblocksError.from(res);
@@ -2433,7 +2503,7 @@ var Liveblocks = class {
2433
2503
  "Content-Type": params.file.type,
2434
2504
  "Content-Length": String(params.file.size)
2435
2505
  },
2436
- signal: _optionalChain([options, 'optionalAccess', _53 => _53.signal])
2506
+ signal: _optionalChain([options, 'optionalAccess', _54 => _54.signal])
2437
2507
  }
2438
2508
  );
2439
2509
  if (!res.ok) {
@@ -2809,7 +2879,7 @@ var WHITESPACE_REGEX = /\s/;
2809
2879
  var MarkedCustomTokenizer = class extends _marked.Tokenizer {
2810
2880
  url(src) {
2811
2881
  const token = super.url(src);
2812
- if (_optionalChain([token, 'optionalAccess', _54 => _54.href, 'access', _55 => _55.startsWith, 'call', _56 => _56("mailto:")])) {
2882
+ if (_optionalChain([token, 'optionalAccess', _55 => _55.href, 'access', _56 => _56.startsWith, 'call', _57 => _57("mailto:")])) {
2813
2883
  return void 0;
2814
2884
  }
2815
2885
  return token;
@@ -2989,7 +3059,7 @@ function tokensToCommentBodyInlines(tokens, formatting = {}) {
2989
3059
  case "escape":
2990
3060
  case "html":
2991
3061
  case "text": {
2992
- if (token.type === "text" && _optionalChain([token, 'access', _57 => _57.tokens, 'optionalAccess', _58 => _58.length])) {
3062
+ if (token.type === "text" && _optionalChain([token, 'access', _58 => _58.tokens, 'optionalAccess', _59 => _59.length])) {
2993
3063
  appendFormattedInlinesFromTokens(inlines, token.tokens, formatting);
2994
3064
  } else {
2995
3065
  appendTextWithMentions(inlines, token.text, formatting);