@liveblocks/node 3.22.0 → 3.23.0-file1

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, 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, 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, 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';
3
3
  import { IncomingHttpHeaders } from 'http';
4
4
 
5
5
  /**
@@ -102,6 +102,10 @@ type AttachmentWithUrl = {
102
102
  url: string;
103
103
  expiresAt: string;
104
104
  };
105
+ type StorageFileUrl = {
106
+ url: string;
107
+ expiresAt: string;
108
+ };
105
109
  type CreateThreadOptions<TM extends BaseMetadata, CM extends BaseMetadata> = {
106
110
  roomId: string;
107
111
  data: {
@@ -976,6 +980,14 @@ declare class Liveblocks {
976
980
  roomId: string;
977
981
  attachmentId: string;
978
982
  }, options?: RequestOptions): Promise<AttachmentWithUrl>;
983
+ uploadFile(params: {
984
+ roomId: string;
985
+ file: File;
986
+ }, options?: RequestOptions): Promise<LiveFile>;
987
+ getFileUrl(params: {
988
+ roomId: string;
989
+ file: LiveFileReference;
990
+ }, options?: RequestOptions): Promise<StorageFileUrl>;
979
991
  /**
980
992
  * Creates a new thread. The thread will be created with the specified comment as its first comment.
981
993
  * If the thread already exists, a `LiveblocksError` will be thrown with status code 409.
@@ -2048,4 +2060,4 @@ declare function isCustomNotificationEvent(event: WebhookEvent): event is Custom
2048
2060
  */
2049
2061
  type RoomPermission = RoomPermissions;
2050
2062
 
2051
- export { type AiCopilot, type CommentCreatedEvent, type CommentDeletedEvent, type CommentEditedEvent, type CommentReactionAdded, type CommentReactionRemoved, type CreateAiCopilotOptions, type CreateFeedMessageOptions, type CreateFeedOptions, type CreateFileKnowledgeSourceOptions, type CreateRoomOptions, type CreateVersionHistorySnapshotResponse, type CreateWebKnowledgeSourceOptions, type CustomNotificationEvent, type GetAiCopilotsOptions, type GetInboxNotificationsOptions, type GetKnowledgeSourcesOptions, type GetRoomsOptions, type GetVersionHistoryOptions, type GetWebKnowledgeSourceLinksOptions, type HistoryVersion, type InboxNotificationsQueryCriteria, type KnowledgeSource, Liveblocks, LiveblocksError, type LiveblocksOptions, type MassMutateStorageCallback, type MassMutateStorageOptions, type MutateStorageCallback, type MutateStorageOptions, type NotificationEvent, type Page, type PaginationOptions, type RoomCreatedEvent, type RoomData, type RoomDeletedEvent, type RoomPermission, type RoomUser, type RoomsQueryCriteria, type SetPresenceOptions, type StorageUpdatedEvent, type TextMentionNotificationEvent, type ThreadCreatedEvent, type ThreadDeletedEvent, type ThreadMarkedAsResolvedEvent, type ThreadMarkedAsUnresolvedEvent, type ThreadMetadataUpdatedEvent, type ThreadNotificationEvent, type ThreadParticipants, type UpdateAiCopilotOptions, type UpdateFeedMessageOptions, type UpdateFeedOptions, type UpdateRoomOptions, type UpsertRoomOptions, type UserEnteredEvent, type UserLeftEvent, type WebKnowledgeSourceLink, type WebhookEvent, WebhookHandler, type WebhookRequest, type YDocUpdatedEvent, isCustomNotificationEvent, isTextMentionNotificationEvent, isThreadNotificationEvent, markdownToCommentBody };
2063
+ export { type AiCopilot, type CommentCreatedEvent, type CommentDeletedEvent, type CommentEditedEvent, type CommentReactionAdded, type CommentReactionRemoved, type CreateAiCopilotOptions, type CreateFeedMessageOptions, type CreateFeedOptions, type CreateFileKnowledgeSourceOptions, type CreateRoomOptions, type CreateVersionHistorySnapshotResponse, type CreateWebKnowledgeSourceOptions, type CustomNotificationEvent, type GetAiCopilotsOptions, type GetInboxNotificationsOptions, type GetKnowledgeSourcesOptions, type GetRoomsOptions, type GetVersionHistoryOptions, type GetWebKnowledgeSourceLinksOptions, type HistoryVersion, type InboxNotificationsQueryCriteria, type KnowledgeSource, Liveblocks, LiveblocksError, type LiveblocksOptions, type MassMutateStorageCallback, type MassMutateStorageOptions, type MutateStorageCallback, type MutateStorageOptions, type NotificationEvent, type Page, type PaginationOptions, type RoomCreatedEvent, type RoomData, type RoomDeletedEvent, type RoomPermission, type RoomUser, type RoomsQueryCriteria, type SetPresenceOptions, type StorageFileUrl, type StorageUpdatedEvent, type TextMentionNotificationEvent, type ThreadCreatedEvent, type ThreadDeletedEvent, type ThreadMarkedAsResolvedEvent, type ThreadMarkedAsUnresolvedEvent, type ThreadMetadataUpdatedEvent, type ThreadNotificationEvent, type ThreadParticipants, type UpdateAiCopilotOptions, type UpdateFeedMessageOptions, type UpdateFeedOptions, type UpdateRoomOptions, type UpsertRoomOptions, type UserEnteredEvent, type UserLeftEvent, type WebKnowledgeSourceLink, type WebhookEvent, WebhookHandler, type WebhookRequest, type YDocUpdatedEvent, isCustomNotificationEvent, isTextMentionNotificationEvent, isThreadNotificationEvent, markdownToCommentBody };
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, 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, 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, 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';
3
3
  import { IncomingHttpHeaders } from 'http';
4
4
 
5
5
  /**
@@ -102,6 +102,10 @@ type AttachmentWithUrl = {
102
102
  url: string;
103
103
  expiresAt: string;
104
104
  };
105
+ type StorageFileUrl = {
106
+ url: string;
107
+ expiresAt: string;
108
+ };
105
109
  type CreateThreadOptions<TM extends BaseMetadata, CM extends BaseMetadata> = {
106
110
  roomId: string;
107
111
  data: {
@@ -976,6 +980,14 @@ declare class Liveblocks {
976
980
  roomId: string;
977
981
  attachmentId: string;
978
982
  }, options?: RequestOptions): Promise<AttachmentWithUrl>;
983
+ uploadFile(params: {
984
+ roomId: string;
985
+ file: File;
986
+ }, options?: RequestOptions): Promise<LiveFile>;
987
+ getFileUrl(params: {
988
+ roomId: string;
989
+ file: LiveFileReference;
990
+ }, options?: RequestOptions): Promise<StorageFileUrl>;
979
991
  /**
980
992
  * Creates a new thread. The thread will be created with the specified comment as its first comment.
981
993
  * If the thread already exists, a `LiveblocksError` will be thrown with status code 409.
@@ -2048,4 +2060,4 @@ declare function isCustomNotificationEvent(event: WebhookEvent): event is Custom
2048
2060
  */
2049
2061
  type RoomPermission = RoomPermissions;
2050
2062
 
2051
- export { type AiCopilot, type CommentCreatedEvent, type CommentDeletedEvent, type CommentEditedEvent, type CommentReactionAdded, type CommentReactionRemoved, type CreateAiCopilotOptions, type CreateFeedMessageOptions, type CreateFeedOptions, type CreateFileKnowledgeSourceOptions, type CreateRoomOptions, type CreateVersionHistorySnapshotResponse, type CreateWebKnowledgeSourceOptions, type CustomNotificationEvent, type GetAiCopilotsOptions, type GetInboxNotificationsOptions, type GetKnowledgeSourcesOptions, type GetRoomsOptions, type GetVersionHistoryOptions, type GetWebKnowledgeSourceLinksOptions, type HistoryVersion, type InboxNotificationsQueryCriteria, type KnowledgeSource, Liveblocks, LiveblocksError, type LiveblocksOptions, type MassMutateStorageCallback, type MassMutateStorageOptions, type MutateStorageCallback, type MutateStorageOptions, type NotificationEvent, type Page, type PaginationOptions, type RoomCreatedEvent, type RoomData, type RoomDeletedEvent, type RoomPermission, type RoomUser, type RoomsQueryCriteria, type SetPresenceOptions, type StorageUpdatedEvent, type TextMentionNotificationEvent, type ThreadCreatedEvent, type ThreadDeletedEvent, type ThreadMarkedAsResolvedEvent, type ThreadMarkedAsUnresolvedEvent, type ThreadMetadataUpdatedEvent, type ThreadNotificationEvent, type ThreadParticipants, type UpdateAiCopilotOptions, type UpdateFeedMessageOptions, type UpdateFeedOptions, type UpdateRoomOptions, type UpsertRoomOptions, type UserEnteredEvent, type UserLeftEvent, type WebKnowledgeSourceLink, type WebhookEvent, WebhookHandler, type WebhookRequest, type YDocUpdatedEvent, isCustomNotificationEvent, isTextMentionNotificationEvent, isThreadNotificationEvent, markdownToCommentBody };
2063
+ export { type AiCopilot, type CommentCreatedEvent, type CommentDeletedEvent, type CommentEditedEvent, type CommentReactionAdded, type CommentReactionRemoved, type CreateAiCopilotOptions, type CreateFeedMessageOptions, type CreateFeedOptions, type CreateFileKnowledgeSourceOptions, type CreateRoomOptions, type CreateVersionHistorySnapshotResponse, type CreateWebKnowledgeSourceOptions, type CustomNotificationEvent, type GetAiCopilotsOptions, type GetInboxNotificationsOptions, type GetKnowledgeSourcesOptions, type GetRoomsOptions, type GetVersionHistoryOptions, type GetWebKnowledgeSourceLinksOptions, type HistoryVersion, type InboxNotificationsQueryCriteria, type KnowledgeSource, Liveblocks, LiveblocksError, type LiveblocksOptions, type MassMutateStorageCallback, type MassMutateStorageOptions, type MutateStorageCallback, type MutateStorageOptions, type NotificationEvent, type Page, type PaginationOptions, type RoomCreatedEvent, type RoomData, type RoomDeletedEvent, type RoomPermission, type RoomUser, type RoomsQueryCriteria, type SetPresenceOptions, type StorageFileUrl, type StorageUpdatedEvent, type TextMentionNotificationEvent, type ThreadCreatedEvent, type ThreadDeletedEvent, type ThreadMarkedAsResolvedEvent, type ThreadMarkedAsUnresolvedEvent, type ThreadMetadataUpdatedEvent, type ThreadNotificationEvent, type ThreadParticipants, type UpdateAiCopilotOptions, type UpdateFeedMessageOptions, type UpdateFeedOptions, type UpdateRoomOptions, type UpsertRoomOptions, type UserEnteredEvent, type UserLeftEvent, type WebKnowledgeSourceLink, type WebhookEvent, WebhookHandler, type WebhookRequest, type YDocUpdatedEvent, isCustomNotificationEvent, isTextMentionNotificationEvent, isThreadNotificationEvent, markdownToCommentBody };
package/dist/index.js CHANGED
@@ -3,12 +3,14 @@ import { detectDupes } from "@liveblocks/core";
3
3
 
4
4
  // src/version.ts
5
5
  var PKG_NAME = "@liveblocks/node";
6
- var PKG_VERSION = "3.22.0";
6
+ var PKG_VERSION = "3.23.0-file1";
7
7
  var PKG_FORMAT = "esm";
8
8
 
9
9
  // src/client.ts
10
10
  import {
11
+ autoRetry,
11
12
  checkBounds,
13
+ chunk,
12
14
  ClientMsgCode,
13
15
  convertToCommentData,
14
16
  convertToCommentUserReaction,
@@ -19,7 +21,10 @@ import {
19
21
  convertToUserSubscriptionData,
20
22
  createManagedPool,
21
23
  createNotificationSettings,
24
+ createStorageFileId,
25
+ getLiveFileId,
22
26
  isPlainObject,
27
+ LiveFile,
23
28
  LiveObject,
24
29
  makeAbortController,
25
30
  normalizeRoomAccesses,
@@ -64,8 +69,8 @@ var LineStream = class extends TransformStream {
64
69
  constructor() {
65
70
  let buffer = "";
66
71
  super({
67
- transform(chunk, controller) {
68
- buffer += chunk;
72
+ transform(chunk2, controller) {
73
+ buffer += chunk2;
69
74
  if (buffer.includes("\n")) {
70
75
  const lines = buffer.split("\n");
71
76
  for (let i = 0; i < lines.length - 1; i++) {
@@ -289,6 +294,120 @@ var Session = class {
289
294
  };
290
295
 
291
296
  // 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 = [
300
+ 2e3,
301
+ 2e3,
302
+ 2e3,
303
+ 2e3,
304
+ 2e3,
305
+ 2e3,
306
+ 2e3,
307
+ 2e3,
308
+ 2e3,
309
+ 2e3
310
+ ];
311
+ async function uploadStorageFile({
312
+ file,
313
+ signal,
314
+ abortErrorMessage,
315
+ uploadSingle,
316
+ createMultipartUpload,
317
+ uploadMultipartPart,
318
+ completeMultipartUpload,
319
+ abortMultipartUpload
320
+ }) {
321
+ const abortError = createAbortError(abortErrorMessage);
322
+ if (signal?.aborted) {
323
+ throw abortError;
324
+ }
325
+ const handleRetryError = (err) => {
326
+ if (signal?.aborted) {
327
+ throw abortError;
328
+ }
329
+ if (err instanceof LiveblocksError && err.status === 413) {
330
+ throw err;
331
+ }
332
+ return false;
333
+ };
334
+ if (file.size <= STORAGE_FILE_PART_SIZE) {
335
+ return autoRetry(
336
+ uploadSingle,
337
+ STORAGE_FILE_RETRY_ATTEMPTS,
338
+ STORAGE_FILE_RETRY_DELAYS,
339
+ handleRetryError
340
+ );
341
+ }
342
+ let uploadId;
343
+ const uploadedParts = [];
344
+ const multipartUpload = await autoRetry(
345
+ createMultipartUpload,
346
+ STORAGE_FILE_RETRY_ATTEMPTS,
347
+ STORAGE_FILE_RETRY_DELAYS,
348
+ handleRetryError
349
+ );
350
+ try {
351
+ uploadId = multipartUpload.uploadId;
352
+ if (signal?.aborted) {
353
+ throw abortError;
354
+ }
355
+ const batches = chunk(splitStorageFileIntoParts(file), 5);
356
+ for (const parts of batches) {
357
+ const uploadedPartPromises = [];
358
+ for (const { part, partNumber } of parts) {
359
+ uploadedPartPromises.push(
360
+ autoRetry(
361
+ () => uploadMultipartPart(multipartUpload.uploadId, partNumber, part),
362
+ STORAGE_FILE_RETRY_ATTEMPTS,
363
+ STORAGE_FILE_RETRY_DELAYS,
364
+ handleRetryError
365
+ )
366
+ );
367
+ }
368
+ uploadedParts.push(...await Promise.all(uploadedPartPromises));
369
+ }
370
+ if (signal?.aborted) {
371
+ throw abortError;
372
+ }
373
+ return completeMultipartUpload(
374
+ multipartUpload.uploadId,
375
+ uploadedParts.sort((a, b) => a.partNumber - b.partNumber)
376
+ );
377
+ } catch (err) {
378
+ if (uploadId && isAbortOrTimeoutError(err)) {
379
+ try {
380
+ await abortMultipartUpload(uploadId);
381
+ } catch {
382
+ }
383
+ }
384
+ throw err;
385
+ }
386
+ }
387
+ function splitStorageFileIntoParts(file) {
388
+ const parts = [];
389
+ let start = 0;
390
+ while (start < file.size) {
391
+ const end = Math.min(start + STORAGE_FILE_PART_SIZE, file.size);
392
+ parts.push({
393
+ partNumber: parts.length + 1,
394
+ part: file.slice(start, end)
395
+ });
396
+ start = end;
397
+ }
398
+ return parts;
399
+ }
400
+ function isAbortOrTimeoutError(err) {
401
+ return err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError");
402
+ }
403
+ function createAbortError(message) {
404
+ if (typeof DOMException === "function") {
405
+ return new DOMException(message, "AbortError");
406
+ }
407
+ const err = new Error(message);
408
+ err.name = "AbortError";
409
+ return err;
410
+ }
292
411
  function inflateRoomData(room) {
293
412
  const createdAt = new Date(room.createdAt);
294
413
  const lastConnectionAt = room.lastConnectionAt ? new Date(room.lastConnectionAt) : void 0;
@@ -359,8 +478,8 @@ var Liveblocks = class {
359
478
  this.#baseUrl = new URL(getBaseUrl(options.baseUrl));
360
479
  this.#localDev = !!options.baseUrl && /^https?:\/\/localhost[:/]/.test(options.baseUrl);
361
480
  }
362
- async #post(path, json, options) {
363
- const url3 = urljoin(this.#baseUrl, path);
481
+ async #post(path, json, options, params) {
482
+ const url3 = urljoin(this.#baseUrl, path, params);
364
483
  const headers = {
365
484
  Authorization: `Bearer ${this.#secret}`,
366
485
  "Content-Type": "application/json"
@@ -375,6 +494,12 @@ var Liveblocks = class {
375
494
  xwarn(res, "POST", path);
376
495
  return res;
377
496
  }
497
+ async #readJsonResponse(res) {
498
+ if (!res.ok) {
499
+ throw await LiveblocksError.from(res);
500
+ }
501
+ return await res.json();
502
+ }
378
503
  async #patch(path, json, options) {
379
504
  const url3 = urljoin(this.#baseUrl, path);
380
505
  const headers = {
@@ -407,6 +532,22 @@ var Liveblocks = class {
407
532
  xwarn(res, "PUT", path);
408
533
  return res;
409
534
  }
535
+ async #putBlob(path, body, params, options) {
536
+ const url3 = urljoin(this.#baseUrl, path, params);
537
+ const headers = {
538
+ Authorization: `Bearer ${this.#secret}`,
539
+ "Content-Type": "application/octet-stream"
540
+ };
541
+ const fetch = await fetchPolyfill();
542
+ const res = await fetch(url3, {
543
+ method: "PUT",
544
+ headers,
545
+ body,
546
+ signal: options?.signal
547
+ });
548
+ xwarn(res, "PUT", path);
549
+ return res;
550
+ }
410
551
  async #delete(path, params, options) {
411
552
  const url3 = urljoin(this.#baseUrl, path, params);
412
553
  const headers = {
@@ -1258,6 +1399,73 @@ var Liveblocks = class {
1258
1399
  }
1259
1400
  return await res.json();
1260
1401
  }
1402
+ async uploadFile(params, options) {
1403
+ const { roomId, file } = params;
1404
+ const fileId = createStorageFileId();
1405
+ const fileData = await uploadStorageFile({
1406
+ file,
1407
+ signal: options?.signal,
1408
+ abortErrorMessage: `Upload of file ${fileId} was aborted.`,
1409
+ uploadSingle: async () => {
1410
+ const res = await this.#putBlob(
1411
+ url2`/v2/rooms/${roomId}/storage/files/${fileId}/upload/${file.name}`,
1412
+ file,
1413
+ { fileSize: file.size },
1414
+ options
1415
+ );
1416
+ return await this.#readJsonResponse(res);
1417
+ },
1418
+ createMultipartUpload: async () => {
1419
+ const res = await this.#post(
1420
+ url2`/v2/rooms/${roomId}/storage/files/${fileId}/multipart/${file.name}`,
1421
+ void 0,
1422
+ options,
1423
+ { fileSize: file.size }
1424
+ );
1425
+ return await this.#readJsonResponse(res);
1426
+ },
1427
+ uploadMultipartPart: async (uploadId, partNumber, part) => {
1428
+ const res = await this.#putBlob(
1429
+ url2`/v2/rooms/${roomId}/storage/files/${fileId}/multipart/${uploadId}/${String(partNumber)}`,
1430
+ part,
1431
+ void 0,
1432
+ options
1433
+ );
1434
+ return await this.#readJsonResponse(res);
1435
+ },
1436
+ completeMultipartUpload: async (uploadId, parts) => {
1437
+ const res = await this.#post(
1438
+ url2`/v2/rooms/${roomId}/storage/files/${fileId}/multipart/${uploadId}/complete`,
1439
+ { parts },
1440
+ options
1441
+ );
1442
+ return await this.#readJsonResponse(res);
1443
+ },
1444
+ abortMultipartUpload: async (uploadId) => {
1445
+ const res = await this.#delete(
1446
+ url2`/v2/rooms/${roomId}/storage/files/${fileId}/multipart/${uploadId}`
1447
+ );
1448
+ if (!res.ok) {
1449
+ throw await LiveblocksError.from(res);
1450
+ }
1451
+ }
1452
+ });
1453
+ return new LiveFile(fileData);
1454
+ }
1455
+ async getFileUrl(params, options) {
1456
+ const { roomId, file } = params;
1457
+ const fileId = getLiveFileId(file);
1458
+ const res = await this.#get(
1459
+ url2`/v2/rooms/${roomId}/storage/files/${fileId}`,
1460
+ void 0,
1461
+ options
1462
+ );
1463
+ const storageFile = await this.#readJsonResponse(res);
1464
+ return {
1465
+ url: storageFile.url,
1466
+ expiresAt: storageFile.expiresAt
1467
+ };
1468
+ }
1261
1469
  /**
1262
1470
  * Creates a new thread. The thread will be created with the specified comment as its first comment.
1263
1471
  * If the thread already exists, a `LiveblocksError` will be thrown with status code 409.
@@ -3081,10 +3289,12 @@ import {
3081
3289
  LiveList,
3082
3290
  LiveMap,
3083
3291
  LiveObject as LiveObject2,
3292
+ LiveFile as LiveFile2,
3084
3293
  stringifyCommentBody
3085
3294
  } from "@liveblocks/core";
3086
3295
  detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
3087
3296
  export {
3297
+ LiveFile2 as LiveFile,
3088
3298
  LiveList,
3089
3299
  LiveMap,
3090
3300
  LiveObject2 as LiveObject,